0

私は "ポータブル"にしたいデータアクセスレイヤライブラリを持っています。私がポータブルであることが好きな理由は、SQL Azure & Azureファイルストレージ(例:data + pdfレポート)とSql Server 2008R2とFile Systemストレージをコンクリートサーバーで使用したいからです。依存性注入コンテナ

スペックに基づいて、システムは、後の実装(SQL +ファイルシステムのストレージ)で稼動するはずですが、会議ではAzureに移行する予定の一定のスケーラビリティのしきい値があります。

私が使用するデータアクセスクラスは、(私が構築した)IDataProviderインターフェイスを実装し、データアクセスの具体的な実装に必要なメソッドを定義します。データアクセス層は、その上にメソッドをIDataProviderインターフェイスを渡し、呼び出しを介して行われるがかかり例:

public Interface IDataProvider 
{ 
    public bool DoSomething(); 
} 

public class AzureDataProvider : IDataProvider 
{ 
    private string ConnectionString; 

    public AzureDataProvider(string connectionString) 
    { 
     this.ConnectionString = connectionString; 
    } 

    public AzureDataProvider():this(
     ConfigurationManager.ConnectionString["conn"].ConnectionString) 
    { 
    } 

    public bool DoSomething() 
    { 
     return false; 
    } 
} 

だから今問題IDataProviderインターフェイス上のメソッドを呼び出すと、消費者のクラスは、次の操作を実行しなければならないことである。

public class DataAccessConsumer 
{ 
    public void SomeOperation() 
    { 
     AzureDataProvider azureProvider = new AzureDataProvider(); 
     IDataProvider dataProvider = (IDataProvider)azureProvider; 

     bool result = dataProvider.DoSomething(); 
    } 
} 

したがって、上記のコードの問題は、クライアントがまだ具体的なAzureDataProviderクラスの知識を持っている必要があることです。すべてのインターフェイスメソッドに接続文字列を渡すことなく、またはすべてのメソッド内でConfigurationManagerを使用して接続文字列を検索することなく、クライアントにIDataProviderインターフェイスだけを提供する方法があります。

これは可能ですか?抽象ファクトリーや何らかの依存性注入コンテナパターンがそのトリックですか?もしそうなら、私はコードサンプル、またはコードサンプルへのリンクを感謝します。

+0

データアクセスコードはどのようなプロジェクトで使用されますか? –

答えて

1

私は自分のDIを公開しました。移植性を達成することが目標であれば、私は半許容可能なソリューションになったと思いますが、欠点は完全に達成できないということですしかし、私のアプリケーションの文脈では十分です。

接続インタフェース:

public interface IConnection 
{ 
    public string ConnectionString; 
} 

コンクリート接続実装

public class Connection: IConnection 
{ 
    public string ConnectionString{ get; set; } 

    public Connection(string connectionString) 
    { 
     this.ConnectionString = connectionString; 
    } 

    public Connection():this(ConfigurtionManager.ConnectionStrings["connection"].ConnectionString) 
    { 
     //Broke DI in the interest of usability. 
    } 
} 

データアクセス層インタフェース

public interface IDataProvider 
{ 
    IConnection Connection; 

    public void Foo(); 
} 

コンクリートデータアクセス層実装

public class AzureProvider : IDataProvider 
{ 
    IConnection Connection { get; set; } 

    public AzureProvider(IConnection connection) 
    { 
     this.Connection = connection; 
    } 

    public void Foo() 
    { 

    } 
} 

DI Conainer /ファクトリー(シングルトンまたは静的クラス)

public static class ProviderFactory 
{ 
    public static IDataProvider GetProvider() //I'd pass parameters if I had more than 1. 
    { 
     Connection connection = new Connection(); //this is why I broke DI. 
     IConnection iConnection = (IConnection)connection; 

     AzureProvider azureProvider = new AzureProvider(iConnection); 
     IDataProvider iDataProvider = (IDataProvider)azureProvider; 

     return iDataProvider; 
    } 
} 

データアクセス層の消費者(このサンプルでは、​​それはページです):

public class SomePage : Page 
{ 
    protected void Page_Load(object sender, EventArgs e) 
    { 
     IDataProvider provider = ProviderFactory.GetProvider(); 
     provider.Foo(); 
    } 
} 

ご覧のとおり、ページはデータアクセスレイヤの実装の詳細を知る必要はありません。 ProviderFactoryがIDataProviderを吐くことができる限り、ページは満足しています。したがって、IDataProviderインターフェイスを実装している限り、SqlStorageProviderというプロバイダを変更する場合、ページのコードを変更する必要はありません。これにより、ソフトウェアアーキテクチャの観点からの真の分離が達成されます。

+1

真のDIを達成するためには、プロバイダファクトリを渡して(自分自身で接続を作成する代わりにConnectionFactoryを使用して)、依存関係として渡す必要があります。 – Arafangion

+0

あなたは正しいです。私はそれについて考えなかった!それに応じて私のデザインを変更します! – bleepzter

1

まず、AzureDataProviderはConfigurationManagerに依存しています。これは代わりに注入する必要があります。

第2に、このDataProviderをDataAccessConsumerに注入する必要があります。

これは、コンテナに依存しないで、現実的なアプリケーションが良い依存性注入を持つことを意味します。しかし、すべての依存関係をまとめて接続する必要があります。これは苦痛です - この配線を解決するために、メインエントリーポイントでのみDependencyInjectionContainerを使用してください。 (これにより、コンテナに「DataAccessConsumerを取得」を依頼することができ、従属性注入フレームワークが依存関係を把握できるので、命令型アプローチではなくより便利な宣言型アプローチを使用できます。

お気に入りの依存関係C#のインジェクションフレームワークはNInject2です

+1

+1また、この回答を展開して、この質問をチェックアウトすることもできます:http://stackoverflow.com/questions/4570750/dependency-injection-turtles-all-the-way-down –

+0

Mark 。これは私が遭遇した最も役立つ記事です。私はArafangionからのコメントに感謝します。しかし、彼は明らかに簡単な説明をしています。 Joe R. – bleepzter