首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MEF2 (System.Composition)中的强类型元数据

MEF2 (System.Composition)中的强类型元数据
EN

Stack Overflow用户
提问于 2012-12-17 12:32:25
回答 1查看 4K关注 0票数 4

我在一个新的System.Composition MVC4项目中使用来自用于web和Windows应用程序的MEF包的ASP.NET命名空间。

朗读中,您不再使用Lazy<IExtension, IExtensionMetadata>了,但是现在您必须为元数据视图提供一个具体的类型(并且可能使用ExportFactory<>而不是Lazy<> ?)。

但是,我找不到任何例子说明这一切应该如何工作-只是几次提到使用一个具体类型而不是一个接口。

我尝试了几种方法,但是仍然得到了以下错误--“丢失了'AccountID‘的导出元数据,并且没有提供默认值”。

我的密码..。

创建容器(在Global.asax或App_Start文件夹中):

代码语言:javascript
复制
// 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()方法:

代码语言:javascript
复制
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:

代码语言:javascript
复制
public interface IExtension
{
    void DoWork();
}

ExtensionMetadata.cs:

代码语言:javascript
复制
public class ExtensionMetadata
{
    public int AccountID { get; set; }
}

ExtensionA.cs (与ExtensionB.cs相同):

代码语言:javascript
复制
public void DoWork()
{
    System.Diagnostics.Debug.WriteLine("ExtensionA doing work..");
}

ExtensionManager.cs:

代码语言:javascript
复制
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();
            }                   
        }           
    }
}

我想我漏掉了一些很重要的东西。基本上,我想要惰性地导入所有扩展,检查它们的元数据,如果满足了条件,就让扩展做一些事情。

非常感谢您的反馈或任何涉及我的场景的示例代码/教程的链接。

非常感谢!

EN

回答 1

Stack Overflow用户

发布于 2012-12-18 06:35:45

我看完这个问题后就想好了。

我创建了一个元数据属性:

代码语言:javascript
复制
[MetadataAttribute]
public class ExtensionMetadataAttribute : ExportAttribute, IExtensionMetadata
{
    public int AccountID { get; set; }

    public ExtensionMetadataAttribute(int accountID) : base(typeof (IExtension))
    {
        AccountID = accountID;
    }
}

然后修改ExtensionA.cs:

代码语言:javascript
复制
[ExtensionMetadata(1)]
public class ExtensionA : IExtension
{
    public void DoWork()
    {
        System.Diagnostics.Debug.WriteLine("ExtensionA doing work..");
    }
}

现在ExtensionManager.cs看起来是这样的:

代码语言:javascript
复制
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();
                }
            }
        }
    }
}

这似乎可以发挥作用,但我仍然感兴趣的任何反馈,再最佳实践,性能问题等。

谢谢!

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13914256

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档