像简单的 Funq 容器一样用 C# 组合 MEF 部件
在 Funq 以及可能大多数其他 IoC 容器中,我可以简单地执行此操作来配置类型:
container.Register<ISomeThing>(c => new SomeThing());
How Could I fast Extend MEF (或使用现有的 MEF 功能)在不使用属性的情况下执行相同的操作。
我认为我可以这样做:
var container = new CompositionContainer();
var batch = new CompositionBatch();
batch.AddExport<ISomeThing>(() => new SomeThing());
batch.AddExportedValue(batch);
container.Compose(batch);
使用 CompositionBatch
的扩展方法:
public static ComposablePart AddExport<TKey>(this CompositionBatch batch, Func<object> func)
{
var typeString = typeof(TKey).ToString();
return batch.AddExport(
new Export(
new ExportDefinition(
typeString,
new Dictionary<string, object>() { { "ExportTypeIdentity", typeString } }),
func));
}
如果我稍后这样做:
var a = container.GetExport<ISomeThing>().Value;
var b = container.GetExport<ISomeThing>().Value;
两个实例都是相同的。我如何强制(配置)它们为不同的实例?
如果这不是可行的方法,我该如何在 MEF 中执行此操作?
In Funq and probably most other IoC containers I can simply do this to configure a type:
container.Register<ISomeThing>(c => new SomeThing());
How could I quickly extend MEF (or use existing MEF functionality) to do the same without using attributes.
Here is how I thought I could do it:
var container = new CompositionContainer();
var batch = new CompositionBatch();
batch.AddExport<ISomeThing>(() => new SomeThing());
batch.AddExportedValue(batch);
container.Compose(batch);
With this extension method for CompositionBatch
:
public static ComposablePart AddExport<TKey>(this CompositionBatch batch, Func<object> func)
{
var typeString = typeof(TKey).ToString();
return batch.AddExport(
new Export(
new ExportDefinition(
typeString,
new Dictionary<string, object>() { { "ExportTypeIdentity", typeString } }),
func));
}
If I later do:
var a = container.GetExport<ISomeThing>().Value;
var b = container.GetExport<ISomeThing>().Value;
Both instance are the same. How can I force (configure) them to be different instances?
If this is not the way to go, how would I do this in MEF?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我想关键是将委托添加到容器中,例如:
这样您就可以获取委托并执行它:
当然,MEF(Silverlight)确实提供了本机
ExportFactory
(和ExportFactory
类型,支持为每次导入调用创建新实例。您可以通过下载 Glen Block 的 .NET 4.0(桌面)库的 ExportFactory 。I would imagine the key is to add the delegate to the container, e.g.:
That way you can grab the delegate and execute it:
Of course, MEF (Silverlight) does provide a native
ExportFactory<T>
(andExportFactory<T,TMetadata>
type that supports the creation of new instances for each call to import. You can add support for this by downloading Glen Block's ExportFactory for .NET 4.0 (Desktop) library.如果你不想使用属性,你可以使用这个技巧(基于标记Seemann 的博文)。
首先,创建一个如下所示的通用类:
现在您可以在容器中注册您想要的任何类,如下所示:
或者,您可以实现从 ExportProvider,它允许您几乎复制 Funq 的工作方式:
If you don't want to use attributes, you can use this trick (based on Mark Seemann's blogpost).
First, create a generic class like this:
Now you can register any class you want in the container, like this:
Alternatively, you could implement your own export provider derived from ExportProvider, which allows you to pretty much duplicate Funq's way of working:
只需像这样标记
SomeThing
类:然后无论您在何处导入
ISomeThing
,您都会获得不同的实例。或者,您还可以在导入时设置所需的创建策略:
Simply mark the
SomeThing
class like this:And then you will get different instances wherever you import
ISomeThing
.Alternatively, you can also set a required creation policy on an import:
在 Glen Block 的 Skydrive 目录中链接到 Matthew Abbott 的回答 我发现了一些看起来简单且轻量级的东西:
FuncCatalog
。在这里下载:FuncCatalogExtension。使用该项目中的几个小类,我现在可以执行以下操作:
In Glen Block's Skydrive directory linked to in Matthew Abbott's answer I found something that seems simple and lightweight: A
FuncCatalog
. Download it here: FuncCatalogExtension.Using the few little classes from that project I could now do this: