2016-09-06 11 views
0

私が作成したとIDataProviderインターフェイスと、このようにそれを実装している:依存性注入を改善する方法は?

public class DatabaseDataProviderBase : IDataProvider 
{ 
    private readonly IDatabaseConnectionStringProvider _databaseConnectionStringProvider; 
    private readonly IParameterApplicator<string> _sqlParameterApplicator; 
    private readonly IDatabaseDataProvider _databaseDataProvider; 

    public DatabaseDataProviderBase(IDatabaseConnectionStringProvider databaseConnectionStringProvider, IParameterApplicator<string> sqlParameterApplicator, IDatabaseDataProvider databaseDataProvider) 
    { 
     _databaseConnectionStringProvider = databaseConnectionStringProvider; 
     _sqlParameterApplicator = sqlParameterApplicator; 
     _databaseDataProvider = databaseDataProvider; 
    } 

    public DataSet GetData(SqlResource sqlResource, List<Parameter> parameters) 
    { 
     var connectionString = _databaseConnectionStringProvider.Get(sqlResource.SqlConnection); 
     var selectQuery = _sqlParameterApplicator.Apply(parameters, sqlResource.SelectQuery); 
     var dataSet = _databaseDataProvider.Get(connectionString, selectQuery); 

     return dataSet; 
    } 
} 

今、私はこのクラスから継承するクラスの多くが必要になります。すなわち、NpgsqlDataProvider,MsSqlDataProvider,OdbcDataprovider以上。これらのクラスのそれぞれは、IDatabaseConnectionStringProviderIDatabaseDataProviderという独自の実装を持ちます。どのインプリメンテーションをNinjectモジュールでバインドして使用するかを指示します。

これは正しい方法ですか、それとももっと良い解決策がありますか?その前に私は前述のインターフェイスの必要な実装を作成した多くの工場を使用していたので、すぐにそれを維持するのは悪夢となりました。しかし、今、これはより良いアプローチのようです - 私は継承し、継承クラスの必要な依存関係を継承するベースクラスを持っています。

しかし、継承されたクラスはただ空です。これらはこの基本クラスDatabaseDataProviderBaseの実装を使用しています。そのため、私は何か間違ったことを感じます。アドバイスありがとうございます。

答えて

0

完全性のために派生クラスは必要ありません。基本クラスはすでに完成しています。

ポイントはあなたがクラスを消費する方法です。あなたは単にIDataProviderを使いますか?

IDataProvider consumer = new ... 

もしそうなら、問題はデータプロバイダを新しくすることにあるかもしれません。あなたはその目的のために工場を使用することができますし、それを使って行うこと:

void Consumer(Func<IDataProvider> providerFactory) 
{ 
    IDataProvider provider = providerFactory(); 
    ... 
} 

このように、あなただけのすべてを消費クラスにプロバイダファクトリを記入し、それらを抽象データプロバイダを使用できるようにする必要があります。 1つのFunc<IDataProvider>デリゲートまたはその他のデリゲートを提供できるのであれば、派生クラスは必要ありません。

+0

コンストラクタインジェクションを使用してコンシューマに 'IDataProvider'を注入したいと思います。しかし、クラスを派生させず、ninjectモジュールで具体的なバインディングを指定しない場合、ベースクラスはどのように 'IDatabaseConnectionStringProvider'の実装を使用するかを知ることができますか? –

+0

しかし、接続文字列プロバイダは、データプロバイダのコンストラクタ引数です。消費者はそれを知る必要はありません。 Ninjectはより細かいセットアップをサポートします。詳細は、ドキュメントを参照してください:https://github.com/ninject/Ninject/wiki/Contextual-Binding –