Hi Kathleen,
Here is a response from Kevin on the MEF team.
Yes it is possible to export generics using RegistrationBuilder.
There is a bug in Desktop MEF that we didn’t fix. We did fix it in Oob MEF.
The work around is to use code like this, the bold is what she needs to add the rest is to make it a complete sample:
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.ComponentModel.Composition.Registration;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication26
{
publicinterfaceIRepository<T>
{
IEnumerable<T> GetItems();
}
publicclassExampleRepository<T> :IRepository<T>where T :class
{
publicIEnumerable<T> GetItems()
{
returnnewList<T>();
}
}
[Export]
publicclassImporter
{
[ImportMany]
publicIEnumerable<string> Items;
}
classProgram
{
privatestaticbool IsGenericDescendentOf(TypeInfo openType, TypeInfo baseType)
{
if (openType.BaseType == null)
{
returnfalse;
}
if (openType.BaseType == baseType.AsType())
{
returntrue;
}
foreach (Type typein openType.ImplementedInterfaces)
{
if (type.IsConstructedGenericType && (type.GetGenericTypeDefinition() == baseType.AsType()))
{
returntrue;
}
}
return IsGenericDescendentOf(IntrospectionExtensions.GetTypeInfo(openType.BaseType), baseType);
}
privatestaticbool IsDescendentOf(Type type, Type baseType)
{
if (((type == baseType) || (type == typeof(object))) || (type == null))
{
returnfalse;
}
TypeInfo typeInfo = IntrospectionExtensions.GetTypeInfo(type);
TypeInfo info2 = IntrospectionExtensions.GetTypeInfo(baseType);
if (typeInfo.IsGenericTypeDefinition)
{
return IsGenericDescendentOf(typeInfo, info2);
}
return info2.IsAssignableFrom(typeInfo);
}
staticvoid Main(string[] args)
{
var reg = newRegistrationBuilder();
reg.ForTypesMatching((t) =>
{
return IsDescendentOf(t, typeof(IRepository<>));
}).Export((eb) => eb.AsContractType(typeof(IRepository<>)));
var cat = newTypeCatalog(newType[] {typeof(ExampleRepository<>),typeof(Importer) }, reg );
var container = newCompositionContainer(cat);
var importer = container.GetExportedValue<Importer>();
if (importer.Items == null)
{
Console.WriteLine("Failed");
}
}
}
}
hth
cheers
-alok
From: KathleenDollard [email removed]
Sent: Sunday, January 20, 2013 2:53 PM
To: Alok Shriram
Subject: Resolving Open Generics with RegistrationBuilder [MEF:430218]
From: KathleenDollard
My open generic works fine when exported with an attribute, such as
[Export(typeof(IRepository
However, I haven't been able to work out how to export this with RegistrationBuilder. Neither of these work
builder.ForTypesDerivedFrom(typeof(IRepository
<>)).ExportInterfaces();
builder.ForTypesDerivedFrom(typeof(IRepository<>)).Export(eb => eb.AsContractType(typeof(IRepository
<>)));
Has anyone worked out how to export open generics from RegistrationBuilder?
Is it impossible?
<>))]
publicclassExampleRepository<T> :IRepository<T> whereT :class