0

インポートされた属性から情報を取得するときに問題が発生します。.ComposeParts()を呼び出した後、属性はnullのままですが、後で.GetExportedValues()を呼び出すことができ、必要なインスタンスを取得できるため、構成は問題ありません。コードは次のとおりです。

作曲を行うブートストラッパー

 [Export]
public class Bootstrapper
{
    public void Run()
    {
        doComposition();
    }

    private void doComposition()
    {
        var catalog = new AggregateCatalog();

        catalog.Catalogs.Add(new DirectoryCatalog("./Applications"));
        catalog.Catalogs.Add(new AssemblyCatalog(typeof(Loader).Assembly));

        Container = new CompositionContainer(catalog);
        // Apps = Container.GetExportedValues<IApplication>(); - this gets me the IApplication(s), but I dont understand why Apps isn't injected automatically
        Container.ComposeParts(catalog);
        IEnumerable<IApplication> app = Container.GetExportedValues<IApplication>();
    }

    public CompositionContainer Container { get; set; }

    private IEnumerable<IApplication> apps;

    [ImportMany(typeof(IApplication))]
    public IEnumerable<IApplication> Apps
    {
        get { return apps; }
        set
        {
            apps = value;
        }
    }

IApplicationを実装するクラスの1つの署名

[Export(typeof(IApplication))]
public class MDFApplication : IApplication {...}

どんなポインタでもありがたいです、どうもありがとう。

4

1 に答える 1

2

Bootstrapper クラスを作成するためにコードを呼び出すことはありません。ComposeParts はカタログを作成しますが、具体的に要求するまでクラスを作成または構成しません。

GetExportedValues を呼び出すと、コンテナーはインポートを必要とするすべてのメンバーを検索しません。既存のインスタンスを返すか、すべてのインポート属性を満たす新しいインスタンスを作成します。

つまり、次のコードは完全に構築された Bootstraper クラスを返します。

        var b= Container.GetExportedValue<Bootstrapper>();
        Debug.Assert(b.Apps!=null);            

既に存在するオブジェクトを作成するには、SatisfyImportsOnce メソッドを呼び出す必要があります。これにより、すべてのインポートが検出され、可能であればそれらが満たされます。例えば

        Container.SatisfyImportsOnce(this);
        Debug.Assert(this.Apps != null);
于 2012-02-01T11:39:39.017 に答える