Resolving Closed Generic Type in Open Generic Type

Sep 23, 2011 at 1:29 AM

I've run into a problem with the Open Generic type support in the latest drop of MEF and I'm hoping someone can either confirm as a known issue or provide me with some help. In a nutshell, I believe MEF is having an issue Importing a Closed Generic Type into an Open Generic Type it is composing. For example:

[Export]
public class BasicType { }

public interface IOpenGeneric<T> { }

[Export(typeof(IOpenGeneric<>))]
public class OpenGeneric<T> : IOpenGeneric<T>
{
    [ImportingConstructor]
    public OpenGeneric(BasicType import) { }
}

works fine when invoked via:

var withOpenType = container.GetExport<IOpenGeneric<BasicType>>().Value;

but the following class:

public interface IOpenGeneric2<T> { }
 
[Export(typeof(IOpenGeneric2<>))]
public class OpenGeneric2<T> : IOpenGeneric2<T> 
{
    [ImportingConstructor]
    public OpenGeneric2(IOpenGeneric<BasicType> import) { }
}

which is importing the same thing as the previous statement does not work when composed using the following:

var withOpenType2 = container.GetExport<IOpenGeneric2<BasicType>>().Value;

however if the constructor is altered to:

[ImportingConstructor] public OpenGeneric2(IOpenGeneric<T> import) { }

everything works fine even though it is effectively identical to the original version.

So...it seems that the only way any type using generic syntax can be imported into an Open Generic type is if it uses the Type Parameters of the Open Type exclusively whcih is a pretty serious limitation in my view. Anyone know a way around this?

Sep 23, 2011 at 6:57 PM

A further error lies in trying to resolve a part that was exported as a Closed Generic type (either by virtue of a hard coded parameter or through the use of the Type Parameter) when it is required by an Open Generic type. The following code will fail to resolve even though a explicit export of Func<BasicType> was registered and the export can be resolved through a call to the GetExport<> method of the container. Note that this scenario holds true even if I manually specify BasicType instead of T in the importing constructor.

public interface IOpenGeneric4<T> { }

[Export(typeof(IOpenGeneric4<>))]
public class OpenGeneric4<T> : IOpenGeneric4<T>
{
    [ImportingConstructor]
    public OpenGeneric4(Func<T> import)
    {
    }
}
Sep 23, 2011 at 6:58 PM

I've also verified that both of these problems are still present in the .NET 4.5 Preview Release

Coordinator
Oct 25, 2011 at 9:58 PM

Thanks for your report.  We are tracking this fix and should have an update soon.

-alok