Assembly.CreateInstance to resolve IoC Container

Multi tool use
Multi tool use


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?





I have edited your title. Please see, "Should questions include “tags” in their titles?", where the consensus is "no, they should not".
– John Saunders
Jun 17 '14 at 6:39




5 Answers
5



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





What if I don't have access to my container? For example, I'm trying to instantiate an object via Reflection in a class library, but the root composition resides in the consumer application.
– Shervin Shahrdar
May 7 at 21:28





@ShervinShahrdar - If you are in an isolated class library why do you need resolving via an ioc container (that needs to be configured in your application)? Seems like you should use Activator.CreateInstance instead to avoid bad design and a dependency to an IOC container. If you really need a resolver for some reason, create an interface IResolver, inject it as a dependency into your class library and use it. Whoever will consume your class library will need to provide a IResolver.
– Amir Popovich
May 8 at 5:10





I am using Activator.CreateInstance. Consider this scenario: I have this class called ActionActivator, which resides in my isolated library. ActionActivator is responsible for instantiating and executing code modules based on an assembly and a class name. The problem is: ActionActivator takes in a number of dependencies via constructor, and supplies them to each activated action. My main problem is that this list of dependencies is going to exponentially grow when the number of my actions grow (e.g., I'll have 30 actions with 6 dependencies each)
– Shervin Shahrdar
May 8 at 13:46






@ShervinShahrdar - Provide the ActionActivator a IResolver as a dependency. The IResolver can have a couple of implementations and since there is an application which is going to use the ActionActivator, it will provide the resolver. This is similiar to how Asp.net resolves things. You provide it a DependecyResolver (it has a default implementation of Activator) and it uses the provided resolver to resolve stuff. Your resolver will use your container that is configured at the application level. Your class lib will have no dependecy to Unity since the interface breaks the coupling.
– Amir Popovich
May 8 at 14:04





That's essentially a ServiceLocator, which is considered an "Anti-Pattern", isn't it? I also don't want to force the consumers of my API to use an IoC container. They might be using Poor man's DI.
– Shervin Shahrdar
May 8 at 14:22



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



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



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



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.





In 15 minutes of coding you could have a simple function that would resolve constructor arguments recursively. It is definitely not a dead end.
– Wiktor Zychla
Jun 17 '14 at 6:45






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

g7qBKyqcOoxtabYB 6K,YMNq5xOFOdGCX7H,rv azJeHed8ClE5 k3,59pW4mOhbQ
rkoRLUG48A5Bd,PMBi LD,1ey8pOJ3b SLPq elZMgptUz7

Popular posts from this blog

PHP contact form sending but not receiving emails

Do graphics cards have individual ID by which single devices can be distinguished?

Create weekly swift ios local notifications