dimanche 17 novembre 2019

How to create instance of property when it called using Reflection?

First, Please see some class:

public class A
{
    public int Id { get; set; }
    public void Run()
    {
        Console.WriteLine("A Run");
    }
}
public class B
{
    public int Id { get; set; }
    public void Run()
    {
        Console.WriteLine("B Run");
    }
}
public class Context
{
    public Context()
    {
        A = new A();
        B = new B();
    }
    public A A { get; set; }
    public B B { get; set; }
}
public class Client
{
    public void Run()
    {
        Context context = new Context();
        context.A.Run();
        context.B.Run();
    }
}

As you can see, inside Context class, have A and B properties, and in constructor of Context, I initialization them.

But, In Context class maybe have a lot of properties like that. So, I wrote some code using Reflection to auto initialization all of properties, code of Context class changed like this:

public class Context
{
    public Context()
    {
        var type = this.GetType();
        var properties = type.GetProperties();
        foreach (var property in properties)
        {
            var instance = property.GetValue(this, null);
            if(instance == null)
            {
                var myInstance = property.PropertyType;
                property.SetValue(this, Activator.CreateInstance(myInstance));
            }
        }
    }
    public A A { get; set; }
    public B B { get; set; }
}

Okay, my code is working fine. But, I'm thinking. In Context class have a lot of properties. And when I initialization Context class, then so many properties inside will be initialization according to it. Whether it's affect to performance of my app?

So, I have a ideal, a property of Context just initialization when it called. Example, when call context.A.Run(), if A property is null, it's will initialization. So, I trying to wrap properties and change Context code like that:

public class Wrapper<T> where T : class
{

}
public class Context
{
    public Context()
    {
        var type = this.GetType();
        var properties = type.GetProperties().Where(p => p.PropertyType.IsGenericType && (typeof(Wrapper<>).IsAssignableFrom(p.PropertyType.GetGenericTypeDefinition()) || p.PropertyType.GetInterface(typeof(Wrapper<>).FullName) != null));

        foreach (var property in properties)
        {
            var instance = property.GetValue(this, null);
            if (instance == null)
            {
                var myInstance = typeof(Wrapper<>);
                var typeArgument = property.PropertyType.GetGenericArguments().FirstOrDefault();

                var instanceGeneric = myInstance.MakeGenericType(typeArgument);
                property.SetValue(this, Activator.CreateInstance(instanceGeneric));
            }
        }
    }
    public Wrapper<A> A { get; set; }
    public Wrapper<B> B { get; set; }
}

And I stuck in here. I have no ideal in Wrapper class.

How can I do that?





Aucun commentaire:

Enregistrer un commentaire