簡體   English   中英

MEF2中強類型元數據(System.Composition)

[英]Strongly typed metadata in MEF2 (System.Composition)

我在新的ASP.NET MVC4項目中使用來自MEF的System.Composition命名空間用於Web和Windows應用商店應用NuGet包

我已經讀過 ,在MEF2中你不再使用Lazy<IExtension, IExtensionMetadata> ,但是現在你必須為元數據視圖提供一個具體的類型(並且可能使用ExportFactory <>而不是Lazy <>?)。

但是,我找不到任何關於它應該如何工作的例子 - 只是提到使用具體類型而不是接口。

我嘗試了一些事情,但不斷收到以下錯誤 - “ 缺少'AccountID'的導出元數據,並且沒有提供默認值 ”。

我的代碼......

創建容器(在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()方法:

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:

public interface IExtension
{
    void DoWork();
}

ExtensionMetadata.cs:

public class ExtensionMetadata
{
    public int AccountID { get; set; }
}

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

public void DoWork()
{
    System.Diagnostics.Debug.WriteLine("ExtensionA doing work..");
}

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();
            }                   
        }           
    }
}

我想我在這里缺少一些非常重要的東西。 基本上我想懶洋洋地導入所有擴展,檢查他們的元數據,如果條件滿足,該擴展做什么。

非常感謝您的反饋或任何涵蓋我的場景的示例代碼/教程的鏈接。

非常感謝!

我想在讀完這個問題后我已經解決了。

我創建了一個元數據屬性:

[MetadataAttribute]
public class ExtensionMetadataAttribute : ExportAttribute, IExtensionMetadata
{
    public int AccountID { get; set; }

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

然后修改了ExtensionA.cs:

[ExtensionMetadata(1)]
public class ExtensionA : IExtension
{
    public void DoWork()
    {
        System.Diagnostics.Debug.WriteLine("ExtensionA doing work..");
    }
}

現在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();
                }
            }
        }
    }
}

這似乎可以解決問題,但我仍然會對任何反饋最佳實踐,性能問題等感興趣。

謝謝!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM