4

新しいASP.NETMVC4プロジェクトで、MEFforWebおよびWindowsStoreアプリのNuGetパッケージのSystem.Composition名前空間を使用しています。

MEF2では使用しなくなったことを読みましLazy<IExtension, IExtensionMetadata>たが、メタデータビューに具体的な型を指定する必要があります(Lazy <>?の代わりにExportFactory <>を使用する可能性があります)。

ただし、これがすべてどのように機能するかについての例は見つかりません。インターフェイスの代わりに具象型を使用することについての言及がいくつかあります。

いくつか試しましたが、次のエラーが発生し続けます-「'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();
            }                   
        }           
    }
}

私はここでかなり大きな何かが欠けていると思います。基本的に、すべての拡張機能を遅延インポートし、それらのメタデータを確認し、条件が満たされている場合は、その拡張機能に何かを実行させたいと思います。

私のシナリオをカバーするサンプルコード/チュートリアルへのフィードバックまたはリンクを本当にいただければ幸いです。

どうもありがとう!

4

1 に答える 1

3

この SO questionを読んだ後、解決したと思います。

メタデータ属性を作成しました:

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

これでうまくいくようですが、ベスト プラクティスやパフォーマンスの問題などに関するフィードバックをお待ちしております。

ありがとう!

于 2012-12-18T06:35:45.420 に答える