user3117252
user3117252

Reputation: 399

Assembly.CreateInstance to resolve IoC Container

I am trying to create an instance of a class (at runtime via a string) using the following code:

Assembly assembly = Assembly.GetAssembly(typeAssembly);
object instance = assembly.CreateInstance(typeName); //throws MissingMethodException
Type classType = instance.GetType();

However, the class I'm trying to instantiate has two parameters in the constructor which is resolved by the Unity IoC container.

When I execute the above code, it throws 'System.MissingMethodException'.

I have searched around the web and it appears that Assembly.CreateInstance won't be able to resolve Unity dependency-injection.

Is this a dead-end or is there a way I can instantiate the class using "CreateInstance" method AND resolve the Unity dependencies?

Upvotes: 14

Views: 15616

Answers (5)

jgauffin
jgauffin

Reputation: 101150

If you have unity in a static property somewhere you can do the following:

Assembly assembly = Assembly.GetAssembly(typeAssembly);
//get the type
Type classType = assembly.GetType(typeName);

//using a static property
var instance = YourApp.Unity.Resolve(classType);

Upvotes: 0

Amir Popovich
Amir Popovich

Reputation: 29836

CreateInstance can recieve params, you can call it this way with ctor params:

(T)Activator.CreateInstance(typeof(T), param1, param2);

Activator.CreateInstance has no idea you have IOC modules in you application. It simply creates an instance of a type.

Now you have two options:

1.Create the instance without the activator using your IOC manager - This seems to me the correct way to do things and probally what you are looking for. Your IOC manager(Unity) resolves types while injecting all dependencies.

var instance = UnityManager.Resolve(typeName); // UnityManager is a manager that holds your unity container.

2.Get the ctor params using Unity and creating the instance without injections(Activator + simple parameter passing). You probally DONT want to do it. I've added this as another explaing example.

var param1 = UnityManager.Resolve(typeOfParam1); 
var param2 = UnityManager.Resolve(typeOfParam2); 
Assembly assembly = Assembly.GetAssembly(typeAssembly);
object instance = assembly.CreateInstance(typeName, param1,param2);

Upvotes: 9

Stephen Zeng
Stephen Zeng

Reputation: 2818

Or you can inject the parameters into the class where you want to create the instance. Then something like this

        var assembly = Assembly.GetAssembly(assemblyType);
        var type = assembly.GetType(typeName);
        var instance = Activator.CreateInstance(type, parameter1, parameter2);

Upvotes: 1

IanT8
IanT8

Reputation: 2217

Well, you have two choices

1) Ask Unity for an instance of the class. Unity will have to resolve the constructor argument dependencies. You don't care as it's Unity's responsibility to give you an instance. However, I'm guessing for some reason, Unity's not initialized or not available.

2) For "typeName", pick an appropriate constructor, look at the dependencies, instantiate the dependencies yourself (or ask Unity to give you instances of the dependencies), and then invoke the constructor passing in an instance of each dependency.

With many dependency injection mechanisms, dependencies are supplied top down and AFAIK its not normal for a type to include in its constructor a call to "container.Inject(this)". Such a type would be coupled to the container implementation, and reducing dependencies is part of what IOC is all about.

I guess "typeName" must not have a default constructor (MissingMethodException).

Upvotes: 1

TomTom
TomTom

Reputation: 62093

Dead end. Unity is not part of the .NET framework core. How do you expect the activator (CreateInstance) to magically know that and call the unity method to resolve things?

No way.

Upvotes: -4

Related Questions