3

私は CompositionBatch を使用して、構成可能なパーツをコンテナーに追加し、後で再構成によって削除します。構成と再構成のすべてがうまく機能します。しかし、私の問題は、基になるオブジェクトが破棄されないことです。私のコードは次のようになります。

[PartCreationPolicy(CreationPolicy.NonShared)]
[Export]
public class NonShared : IDisposable
{
    public NonShared()
    {
        Console.WriteLine("Constructor of NonShared");
    }

    public void Dispose()
    {
        Console.WriteLine("Disposing NonShared");
    }
}

class Program : IPartImportsSatisfiedNotification
{
    [Import(AllowDefault=true, AllowRecomposition=true)]
    private NonShared _nonShared;

    public void OnImportsSatisfied()
    {
        Console.WriteLine("Program.OnImportsSatisfied()");
    }

    static void Main()
    {
        new Program().Run();
    }

    private void Run()
    {
        var partDefinition = AttributedModelServices.CreatePartDefinition(typeof(NonShared), null);
        var exportingPart = partDefinition.CreatePart();

        var addingBatch = new CompositionBatch();
        addingBatch.AddPart(this);
        addingBatch.AddPart(exportingPart);

        var container = new CompositionContainer();
        container.Compose(addingBatch);

        // Do something.

        var removingBatch = new CompositionBatch();
        removingBatch.RemovePart(exportingPart);

        container.Compose(removingBatch);
    }
}

Nonshared.Dispose() を呼び出したいのですが、そうではありません。AddPart /RemovePart でのパーツの有効期間で説明されているように、この状況では共有されていないパーツを破棄する必要があります。私のコードにいくつかの間違いがありますか?

4

1 に答える 1

1

私の知る限り、CompositionBatch を使用して追加されたパーツは、それらを破棄しない ComposablePartExportProvider (これは実装の詳細です) によって処理されます。エクスポートされたパーツを破棄するのは CatalogPartExportProvider だけです。このプロバイダーを使用するには、MEF にパーツを作成させる必要があります。

これに関する詳細については、Weshaggard による最初の回答を読むことができます.

.NET 4.5 で作業している場合は、MEF2 で導入された規約モデルを使用できます。それ以外の場合は、TypeCatalogをAggregateCatalogと組み合わせて使用​​してコンテナーに型を追加し、CompositionContainer.ReleaseExportを使用して共有されていない部分を自由に解放 (およびサポートされている場合は破棄) し、AggregateCatalog.Catalog を使用できます。コンテナからタイプを削除するには、削除します。

を使用したサンプルを次に示しますTypeCatalog

class Program : IPartImportsSatisfiedNotification
{
    [Import(AllowDefault=true, AllowRecomposition=true)]
    private Lazy<NonShared>_nonShared; //Lazy<T> is needed for ReleaseExport to work.

    public void OnImportsSatisfied()
    {
        Console.WriteLine("Program.OnImportsSatisfied()");
    }

    static void Main()
    {
        new Program().Run();
    }

    private void Run()
    {
        var aggregateCatalog = new AggregateCatalog();
        using (var container = new CompositionContainer(aggregateCatalog ))
        {
            container.ComposeParts(this);
            //Check if the field is injected. It shouldn't be since the 
            //NonShared type is not known to the container yet..
            Console.WriteLine("NonShared field {0}", this._nonShared != null ? "exists" : "does not exist");
            //Add the NonShared type to a type catalog.
            var typeCatalog = new TypeCatalog(typeof(NonShared));
            //Add the TypeCatalog to the AggregateCatalog.
            aggregateCatalog.Catalogs.Add(typeCatalog);
            //Check if the field is injected. This time it should be.
            Console.WriteLine("NonShared field {0}", this._nonShared != null ? "exists" : "does not exist");

            if(this._nonShared != null)
            {
                //Access the lazy object so it gets a value.
                this._nonShared.Value.ToString();
                //Release the part. The Dispose method should be called.
                container.ReleaseExport<NonShared>(this._nonShared);
            }
        }
    }
}

以下を使用して、型カタログ全体の削除を簡単にテストできます。

aggregateCatalog.Catalogs.Remove(typeCatalog);
于 2013-08-20T15:09:05.610 に答える