Search code examples
c#reflectionactivator

How to create the class instances dynamically and call the implementation


I have various interfaces and I need to be able to call them. Here is the base class:

public class MyActorBase<TChild>: ActorBase where TChild : MyActorBase<TChild>
{
    public MyActorBase()
    {
       var actors =  ChildClass
           .GetInterfaces()
           .Where(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IActorMessageHandler<>))
           .Select(x=> (arguments: x.GetGenericArguments(), definition: x))
           .ToImmutableList();

       if (actors.Any())
       {
           var ty = actors.First();
           var obj = Activator.CreateInstance(ty.definition, true);

           // how to call method implementation
       }

    }

    protected sealed override bool Receive(object message) => false;
    private Type ChildClass => ((this as TChild)?? new object()).GetType();
}


public interface IActorMessageHandler<in T>
{
    Task Handle(T msg);
}

I read these blog post:

  1. Dont use Activator.CreateInstance
  2. Linq Expressions
  3. Creating objects performance implications

The writers already knew the type at compile time hence were able to cast correctly. I do not know anything at compile time so I cannot use a generic method or typecast it using () operator or as operator.

UPDATE: I think people are not getting the idea of what I want to achieve. so consider this. I made a nuget package which anyone can depend upon. Somewhere in the world, someone writes this code:

    public class MyMessage
    {
        public int Number { get; }

        public MyMessage(int number) => Number = number;
    }

    public class MyNewActor: MyActorBase<MyNewActor>, IActorMessageHandler<MyMessage>
    {
        public Task Handle(MyMessage msg)
        {
            return Task.CompletedTask;
        }
    }

I want that any class that implements the IActorMessageHandler, i should be able to call its method Handle(T msg). so while I was able to instantiate it (considering that I'm not using any dependency injection) how can I call the method in the most efficient way?

Is there any alternate to reflection?


Solution

  • you should not use Activator.CreateInstance it's very much expensive. instead, you may use Expression.Lamda to create objects in an efficient way.

      var object =  Expression.Lambda<Func<IActorMessageHandler<TChild>>>(Expression.New(ty.definition.Value.GetConstructor(Type.EmptyTypes) ?? throw new 
        Exception("Failed to create object"))
                            ).Compile()();