I have a class with internal constructor and want to Resolve it from Unity (2.0).
public class MyClass {
internal MyClass(IService service) {
}
}
then I'm doing
_container.Resolve<MyClass>();
when I do so I have an exception
Exception is: InvalidOperationException - The type MyClass cannot be constructed.
IService is registered and the only problem is that constructor is internal.
I really want this class to be public, but I want it to be creatable only via a factory (in which I'm actually calling container.Resolve<MyClass>()
).
Is there a way to make Unity see that internal constructor? Like InternalsVisibleTo or something?
It's possible there are workarounds/hacks that would allow you to do this with Unity 9I don't know if any), but in general if you want a class to be managed by Unity (or any IOC container), it needs to be public with a public constructor.
One option might be to make an abstract factory that creates the class that has a public constructor, and keep the class's constructor internal. The downside is then your factory will be managed by Unity, but your class itself will not.
Just make the class internal and the constructor public...
I dug a little into how you might extend Unity for this purpose, and found some interesting information.
First, it seems that Unity selects which constructor to use by internally resolving an
IConstructorSelectorPolicy
. Included in Unity is thepublic abstract class ConstructorSelectorPolicyBase<TInjectionConstructorMarkerAttribute>
, which includes this gem:FindInjectionConstructor
and company areprivate static
methods in this class which ultimately end up callingType.GetConstructors
(the overload with no parameters, which only returnspublic
constructors). This tells me that if you can arrange for Unity to use your own constructor selector policy, which would be able to select any constructor, you are golden.There is good documentation about how to make and utilize your own container extensions, so I imagine it's quite possible to make your own
CustomConstructorSelectorPolicy
that includes the relevant portions ofDefaultUnityConstructorSelectorPolicy
(which derives from the abstract base class and is the default unless you register something else) andConstructorSelectorPolicyBase
(deriving from this directly would probably not work well because key methods are notvirtual
, but you can reuse the code).Therefore I 'd say it's doable with a moderate amount of hassle, but the end result would be quite "pure" from an engineering point of view.
Unity will only look at public constructors, so you need to make this constructor public.
In that case, create a factory:
And register:
And resolve:
You can also use Unity's
InjectionFactory
:For this to work the assembly that holds this code should be able to see the internals of the assembly that holds the
MyClass
. In other words theMyClass
assembly should be marked withInternalsVisibleTo
.What would also work is the following:
Although you won't have to make the constructor public, it is a great way to obfuscate your code :-)