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