ImportCardinalityMismatchException - Requested type has more than one instance

Jan 13, 2012 at 6:27 PM

Is there a way to resolve multiple registrations of the same type (which were exported through MEF) by a UnityContainer?

UnityContainer.ResolveAll<IMyInterface>() returns an empty IEnumerable.

UnityContainer.Resolve() throws the exception in the title.

I would expect to be able to do exports in MEF something like this:

[Export(typeof(IMyInterface))]
[ExportMetadata("Name", "MyType1")]
public class MyType1 : IMyInterface {}

[Export(typeof(IMyInterface))]
[ExportMetadata("Name", "MyType2")]
public class MyType2 : IMyInterface {}

And then resolve the objects either through UnityContainer.ResolveAll<IMyInterface>(); or UnityContainer.Resolve<IMyInterface>("MyType1");

Coordinator
Jan 16, 2012 at 7:37 AM

Hi,

Yes, this scenario is supported. ResolveAll() method is not what you want to use as it returns named instance, and this is not supported in the integration layer. What you can do is you can resolve IEnumerable of IMyInterface like this:

unityContainer.Resolve<IEnumerable<IMyInterface>>()
When resolving types by name, Unity cannot derive information about your metadata key named "Name". You have to pass contract name in the export attribute. Then, you should be fine resolving from Unity using that contract name.
Hope this helps!
Piotr
Jan 17, 2012 at 6:11 PM

unityContainer.Resolve<IEnumerable<IMyInterface>>() works. Thanks for the hint!

However, the Unity's policy injection mechanism does not work with this approach, which was the whole point of my exercise.

I've got the following config file:

    <container name="PolicyInjection">
      <interception>
        <policy name="MyTestPolicy">
          <matchingRule name="TypeMatch" type="TypeMatchingRule">
            <constructor>
              <param name="typeName" value ="IMyInterface"/>
            </constructor>
          </matchingRule>
          <matchingRule name="MemberNameMatch" type="MemberNameMatchingRule">
            <constructor>
              <param name="nameToMatch" value="DoSomething"/>
            </constructor>
          </matchingRule>
          <callHandler name="Handler" type="TestCallHandler">
            <lifetime type="ContainerControlledLifetimeManager"/>
          </callHandler>
        </policy>
      </interception>
    </container>

Policy injection works when I have a single implementation of IMyInterface and do unityContainer.Resolve<IMyInterface>();

But if I have multiple implementations of IMyInterface (as in the original post) and I do unityContainer.Resolve<IEnumerable<IMyInterface>>() the policy injection does not happen.

unityContainer.BuildUp<IMyInterface>(myInstance) does not help either - it also throws the exception in the title.

Any ideas?

Jan 23, 2012 at 8:42 PM

Guys, is there a way to use Unity's Policy Injection when I resolve multiple registrations (which are done through MEF) by a UnityContainer?

unityContainer.Resolve<IEnumerable<IMyInterface>>() returns an IEnumerable<IMyInterface>, but policy injection into each instance of IMyInterface configured in Unity is not done.

Thanks.

Feb 7, 2012 at 2:28 PM
Edited Feb 7, 2012 at 2:30 PM

There is also another option,if you only want to use AOP policy injection of Unity. Call container.BuildUp<InterfaceType> for each instance imported by MEF. The condition for this to work is that you don't register the MEF catalog into the unity container.

 

Feb 7, 2012 at 2:48 PM

This is confirmed!

It's an ugly limiting trick, but still better than nothing.

There is no integration between MEF and UNITY achived. In this solution MEF is used strictly as a DI container and Unity is used for interception. In fact, MefContrib.dll is not required here.