42

私はついに頭をC#のIoCとDIに巻き付け、いくつかのエッジに苦労しています。Unityコンテナーを使用していますが、この質問はもっと広く当てはまると思います。

IoCコンテナを使用して、IDisposableを実装するインスタンスをディスペンスすると、私はびっくりします。Dispose()が必要かどうかをどのように知る必要がありますか?インスタンスはあなたのためだけに作成された可能性があります(したがって、Dispose()する必要があります)。または、ライフタイムが他の場所で管理されているインスタンスである可能性があります(したがって、そうでない方がよいでしょう)。コードには何もわかりません。実際、これは構成に基づいて変更される可能性があります!!! これは私には致命的なようです。

そこにいるIoCの専門家は、このあいまいさを処理するための良い方法を説明できますか?

4

7 に答える 7

17

クラスに注入されたオブジェクトで Dispose() を呼び出したくないことは間違いありません。自分が唯一の消費者であると仮定することはできません。あなたの最善の策は、管理されていないオブジェクトを管理されたインターフェイスにラップすることです。

public class ManagedFileReader : IManagedFileReader
{
    public string Read(string path)
    {
        using (StreamReader reader = File.OpenRead(path))
        {
            return reader.ReadToEnd();
        }
    }
}

これは単なる例です。テキスト ファイルを文字列に読み込もうとしている場合は、File.ReadAllText(path) を使用します。

もう 1 つの方法は、ファクトリを注入してオブジェクトを自分で管理することです。

public void DoSomething()
{
    using (var resourceThatShouldBeDisposed = injectedFactory.CreateResource())
    {
        // do something
    }
}
于 2009-06-18T04:35:06.257 に答える
7

AutoFacは、入れ子になったコンテナーを作成できるようにすることで、これを処理します。コンテナーが終了すると、コンテナー内のすべての IDisposable オブジェクトが自動的に破棄されます。詳細はこちら

.. サービスを解決すると、Autofac は解決された使い捨て (IDisposable) コンポーネントを追跡します。作業単位の最後に、関連付けられている有効期間スコープを破棄すると、Autofac は解決されたサービスを自動的にクリーンアップ/破棄します。

于 2009-06-12T16:59:55.167 に答える
2

一般的に、最善のアプローチは、注入されたものを破棄しないことだと思います。インジェクターが割り当てと割り当て解除を行っていると想定する必要があります。

于 2009-06-12T16:52:48.460 に答える
2

コンテナの前にファサードを置くことで、これも解決できます。さらに、サービスのシャットダウンや起動、ServiceHost の状態遷移など、より豊富なライフサイクルを追跡するように拡張できます。

私のコンテナーは、IServiceLocator インターフェイスを実装する IExtension に存在する傾向があります。これは統一のためのファサードであり、WCf サービスで簡単にアクセスできるようにします。さらに、ServiceHostBase からサービス イベントにアクセスできます。

最終的なコードは、登録されたシングルトンまたは作成されたタイプが、ファサードが追跡するインターフェースのいずれかを実装しているかどうかを確認しようとします。

これらのイベントに縛られているため、タイムリーに処分することはできませんが、少しは役立ちます.

タイムリーに破棄したい場合 (別名、現在とサービスのシャットダウン時)。取得したアイテムは使い捨てであることを知る必要があります。これは、それを処分するビジネス ロジックの一部であるため、IDisposable はオブジェクトのインターフェイスの一部である必要があります。そしておそらく、dispose メソッドが呼び出されることに関連する期待 untestests の検証が必要です。

于 2010-03-12T21:04:32.457 に答える
1

Unity フレームワークでは、注入されたクラスを登録する方法が 2 つあります。シングルトンとして (クラスを解決するときに常に同じクラスのインスタンスを取得します)、または解決ごとにクラスの新しいインスタンスを取得する方法です。

後者の場合、解決済みのインスタンスが不要になったら破棄する責任があります (これは非常に合理的な方法です)。一方、コンテナー (オブジェクトの解決を処理するクラス) を破棄すると、すべてのシングルトン オブジェクトも自動的に破棄されます。

そのため、Unity フレームワークで使い捨てオブジェクトを注入しても問題はないようです。他のフレームワークについては知りませんが、依存性注入フレームワークが十分に堅固である限り、何らかの方法でこの問題を確実に処理できると思います。

于 2009-09-19T20:28:26.797 に答える