[英]Strongly typed metadata in MEF2 (System.Composition)
I'm using the System.Composition namespace from the MEF for web and Windows Store apps NuGet package in a new ASP.NET MVC4 project. 我在新的ASP.NET MVC4项目中使用来自MEF的System.Composition命名空间用于Web和Windows应用商店应用NuGet包 。
I've read that in MEF2 you no longer use Lazy<IExtension, IExtensionMetadata>
, but now you must provide a concrete type for the metadata view (and possibly use ExportFactory<> instead of Lazy<> ?). 我已经读过 ,在MEF2中你不再使用
Lazy<IExtension, IExtensionMetadata>
,但是现在你必须为元数据视图提供一个具体的类型(并且可能使用ExportFactory <>而不是Lazy <>?)。
However, I can't find any examples of how this should all work - just a few mentions of using a concrete type instead of an interface. 但是,我找不到任何关于它应该如何工作的例子 - 只是提到使用具体类型而不是接口。
I've tried a few things, but keep getting the following error - " Export metadata for 'AccountID' is missing and no default value was supplied ". 我尝试了一些事情,但不断收到以下错误 - “ 缺少'AccountID'的导出元数据,并且没有提供默认值 ”。
My code... 我的代码......
Creating the container (in Global.asax or App_Start folder): 创建容器(在Global.asax或App_Start文件夹中):
// Get assemblies that will be providing imports and exports
var assemblies = GetAssemblies();
// Get conventions that will be used to find imports and exports
var conventions = GetConventions();
var container = new ContainerConfiguration().WithAssemblies(assemblies, conventions).CreateContainer();
// Create and apply a MefControllerFactory so controllers can be composed
ControllerBuilder.Current.SetControllerFactory(new MefControllerFactory(container));
GetConventions() method: GetConventions()方法:
private static ConventionBuilder GetConventions()
{
var conventionBuilder = new ConventionBuilder();
conventionBuilder.ForTypesDerivedFrom<IController>().Export();
conventionBuilder.ForTypesDerivedFrom<IExtension>().Export<IExtension>();
conventionBuilder.ForTypesMatching(t => t.Namespace != null && t.Namespace.EndsWith(".Parts")).Export().ExportInterfaces();
return conventionBuilder;
}
IExtension.cs: IExtension.cs:
public interface IExtension
{
void DoWork();
}
ExtensionMetadata.cs: ExtensionMetadata.cs:
public class ExtensionMetadata
{
public int AccountID { get; set; }
}
ExtensionA.cs (same as ExtensionB.cs): ExtensionA.cs(与ExtensionB.cs相同):
public void DoWork()
{
System.Diagnostics.Debug.WriteLine("ExtensionA doing work..");
}
ExtensionManager.cs: ExtensionManager.cs:
public class ExtensionManager
{
private IEnumerable<ExportFactory<IExtension, ExtensionMetadata>> _extensions;
public ExtensionManager(IEnumerable<ExportFactory<IExtension, ExtensionMetadata>> extensions)
{
_extensions = extensions;
}
public void DoWork(int accountID)
{
foreach (var extension in _extensions)
{
if (extension.Metadata.AccountID == accountID)
{
extension.DoWork();
}
}
}
}
I think I'm missing something quite major here. 我想我在这里缺少一些非常重要的东西。 Basically I want to lazily import all Extensions, check their metadata and if a condition is fulfilled have that extension do something.
基本上我想懒洋洋地导入所有扩展,检查他们的元数据,如果条件满足,该扩展做什么。
Would really appreciate your feedback or any links to sample code / tutorials that cover my scenario. 非常感谢您的反馈或任何涵盖我的场景的示例代码/教程的链接。
Many thanks! 非常感谢!
I think I've worked it out after reading this SO question . 我想在读完这个问题后我已经解决了。
I created a Metadata Attribute: 我创建了一个元数据属性:
[MetadataAttribute]
public class ExtensionMetadataAttribute : ExportAttribute, IExtensionMetadata
{
public int AccountID { get; set; }
public ExtensionMetadataAttribute(int accountID) : base(typeof (IExtension))
{
AccountID = accountID;
}
}
Then modified ExtensionA.cs: 然后修改了ExtensionA.cs:
[ExtensionMetadata(1)]
public class ExtensionA : IExtension
{
public void DoWork()
{
System.Diagnostics.Debug.WriteLine("ExtensionA doing work..");
}
}
And now ExtensionManager.cs looks like this: 现在ExtensionManager.cs看起来像这样:
public class ExtensionManager : IExtensionManager
{
private readonly IEnumerable<ExportFactory<IExtension, ExtensionMetadata>> _extensions;
public ExtensionManager(IEnumerable<ExportFactory<IExtension, ExtensionMetadata>> extensions)
{
_extensions = extensions;
}
public void DoWork(int accountID)
{
foreach (var extension in _extensions)
{
if (extension.Metadata.AccountID == accountID)
{
using (var foo = extension.CreateExport())
{
foo.Value.DoWork();
}
}
}
}
}
This seems to do the trick, but I would still be interested in any feedback re best practices, performance issues etc. 这似乎可以解决问题,但我仍然会对任何反馈最佳实践,性能问题等感兴趣。
Thanks! 谢谢!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.