My application is using MEF to export some classes from an external assembly. These classes are setup for constructor injection. The issue I am facing is that
MEF is attempting to instantiate the classes when I try to access them. Is there a way to have Ninject take care of the instantiation of the class?
IEnumerable<Lazy<IMyInterface>> controllers =
mefContainer.GetExports<IMyInterface>();
// The following line throws an error because MEF is
// trying to instantiate a class that requires 5 parameters
IMyInterface firstClass = controllers.First().Value;
Update:
There are multiple classes that implement IMyInterface and I would like to select the one that has a specific name and then have Ninject create an instance of it. I’m not really sure if I want laziness.
[Export(typeof(IMyInterface))]
public class MyClassOne : IMyInterface {
private MyRepository one;
private YourRepository two;
public MyClassTwo(MyRepository repoOne, YourRepository repoTwo) {
one = repoOne;
two = repoTwo;
}
}
[Export(typeof(IMyInterface))]
public class MyClassTwo : IMyInterface {
private MyRepository one;
private YourRepository two;
public MyClassTwo(MyRepository repoOne, YourRepository repoTwo) {
one = repoOne;
two = repoTwo;
}
}
Using MEF, I would like to get either MyClassOne or MyClassTwo and then have Ninject provide an instance of MyRepository and YourRepository (Note, these two are bound in a Ninject module in the main assembly and not the assembly they are in)
You could use the Ninject
Loadmechanism to get the exported classes into the mix, and the you either:The creation is lazy (i.e., each impl of
IMyInterfaceis created on the fly as you iterate over the above) IIRC, but have a look at the tests in the source (which is very clean and readable, you have no excuse :P) to be sure.If you dont need the laziness, use LINQ’s
ToArrayorToListto get aIMyInterface[]orList<IMyInterface>or you can use the low-level
Resolve()family of methods (again, have a look in the tests for samples) to get the eligible services [if you wanted to do some filtering or something other than just using an instance – though binding metadata is probably the solution there]Finally, if you can edit in an explanation of whether you need laziness per se or are doing it to illustrate a point. (and have a search for
Lazy<T>here and in general wrt both Ninject and autofac for some samples – cant recall if there are any examples in the source – think not as it’s still on 3.5)EDIT: In that case, you want a bind that has:
in the registrations in your modules in the child assembly.
Then when you’re resolving in the parent assembly, you use the
Kernel.Get<>overload that takes anameparameter to indicate the one you want (no need for laziness, arrays orIEnumerable). TheNamedmechanism is a specific (just one or two helper extensions implement it in terms of the generalised concept) application of the binding metadata concept in Ninject – there’s plenty room to customise it if somethng beyond a simple name is insufficient.If you’re using MEF to construct the objects, you could use the
Kernel.Inject()mechanism to inject properties. The problem is that either MEF or Ninject– has to find the types (Ninject: generally via
Bind()inModules or via scanning extensions, after which one can do aResolveto subset the bindings before instantiation – though this isnt something you normally do)– has to instantiate the types (Ninject: typically via a
Kernel.Get(), but if you discovered the types via e.g. MEF, you might use theKernel.Get(Type)overloads )– has to inject the types (Ninject: typically via a
Kernel.Inject(), or implicit in the `Kernel.Get())What’s not clear to me yet is why you feel you need to mix and mangle the two – ultimately sharing duties during construction and constructor injection is not a core use case for either lib, even if they’re both quite composable libraries. Do you have a constraint, or do you have critical benefits on both sides?