Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 381
user3117252 Avatar asked Jun 17 '14 06:06

user3117252


3 Answers

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);
like image 189
Amir Popovich Avatar answered Oct 16 '22 14:10

Amir Popovich


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).

like image 22
IanT8 Avatar answered Oct 16 '22 15:10

IanT8


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);
like image 33
Stephen Zeng Avatar answered Oct 16 '22 15:10

Stephen Zeng