1

依存性注入パターンの実装について質問があります。Web サービスへのアクセスを必要とするクラスがあります。このパターンによると、クラスでサービスをインスタンス化する必要はありません。これにより、サービスとの強い依存関係が生じるためです。これにより、クラスを構築するファクトリ クラスを作成し、そのコンストラクターで必要な正しいサービス、つまり依存関係を渡します。

私にとって厄介なのは、Web サービス クライアントのインスタンスをオブジェクトに渡しているのに、サービスを開いたままにしないことです。

インターフェイスだけではなく、クライアント全体を渡す必要がありますか? このようにして IDisposable を実装し、サービスへの接続を閉じることができますか?

前もって感謝します。用語を自由に修正してください。混乱を招くつもりはありません。

例えば:

public class ProductService
{
    private IProductService client;

    public ProductService(IProductService client)
    {
        this.client = client;
    }

    public void DoIt()
    {
        client.MyWebMethod();
    }
}

public class Factory
{
    public static T Create<T>() where T : class
    {
        T item = null;

        if (typeof(T) == typeof(ProductService))
        {
            item = new CustomerService(**new ProducttServiceClient()**) as T;
        }
        return item;
    }
}
4

2 に答える 2

0

はい、自分でインスタンスを作成した場合はnew ProducttServiceClient()、工場で破棄する必要があります。Unity、Castle Windsor などの DI コンテナーを使用して解放/破棄できる場所です。

生成されたサービス クライアント ProducttServiceClient (ClientBase のサブクラス) について話していると仮定すると、クライアントを破棄すると、中断されたチャネルではなく、開いているチャネルを閉じようとするため、例外が発生する可能性があることに注意してください。詳細はこちらのリンクをご覧ください

開いているチャネル (System.ServiceModel.ClientBase.CreateChannel()) を渡すだけで、チャネルを閉じて中止し、クライアントを再利用できます。

于 2013-06-07T00:38:34.340 に答える
0

はい、ファクトリ クラスがサービス クライアント インスタンスを作成する場合、それを閉じることも担当する必要があります。しかし、何を達成しようとしているのでしょうか (依存性注入とファクトリ パターンを試すことを除く)。この場合、ファクトリパターンはあまり役に立たないと思います。

サービス操作を呼び出すたびにクライアントがプロキシを作成して閉じることを望まない場合は、ICommunicationObject で拡張メソッドを作成し、作業を実行してからプロキシを閉じることをお勧めします。その後、クライアントを破棄するためのロジックを 1 回 (そして 1 か所で) 実装するだけで済みます。

拡張子は次のようになります。

public static TResult Using<T, TResult>(this T client, Func<T, TResult> work) where T : ICommunicationObject
{
    TResult res = default(TResult);
    try
    {
        res = work(client);
        client.Close();
    }
    catch (CommunicationException)
    {
        client.Abort();
            throw;
    } // ... more catch cases might go here... 
    finally
    {
        if (client.State != CommunicationState.Closed)
            client.Abort();
    }

    return res;
}

クライアントは次のようにメソッドを呼び出します。

using TheNameOfYourNamespaceDefiningTheExtension

return new ServiceClient().Using(client => client.MethodName(request));
于 2013-06-07T09:04:08.523 に答える