Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using ActivatorUtilities.CreateInstance To Create Instance From Type

I am trying to rewrite some code in .Net Core using the built in .Net Dependency Injection. Previously, I was using the current code to create the instance (It was using Unity for DI) which worked great.

var instance = (IPipe)UnityHelper.Container.Resolve(implementation);

For .Net Core I firstly tried the standard Activator.CreateInstance and this worked fine and created the instance of IPipe I was expecting.

var instance = (IPipe)Activator.CreateInstance(implementation)

However. The issue then, is if the implementations are injecting services in the ctor then they won't be resolved (Which is why I was using the Unity.Resolve in the previous project to get around this).

After some research, I found out about the ActivatorUtilities class and I've swapped this out for the code below (serviceProvider is IServiceProvider)

var instance = ActivatorUtilities.CreateInstance<IPipe>(serviceProvider, implementation);

However, I am now getting the current error.

A suitable constructor for type 'IPipe' could not be located. Ensure the type is concrete and services are registered for all parameters of a public constructor.

I don't understand why Activator.CreateInstance works fine but this is complaining about the IPipe constructor?

like image 229
YodasMyDad Avatar asked Oct 04 '18 10:10

YodasMyDad


1 Answers

The generic ActivatorUtilities.CreateInstance<T>(IServiceProvider, Object[]) will actually create an instance of type T and attempt to resolve the type’s constructor arguments using the service provider. The object array you can pass is for additional constructor arguments that are not provided by the service provider.

If you just want to create an instance of a runtime type and have the DI container inject the dependencies, then you will need to use the non-generic ActivatorUtilities.CreateInstance(IServiceProvider, Type, Object[]).

That method returns an object, so you have to type-cast it, if you want to use it. For example:

var instance = (IPipe)ActivatorUtilities.CreateInstance(serviceProvider, pipeType);
like image 64
poke Avatar answered Nov 15 '22 15:11

poke