1

私はUnityを使用して複数のデータベースを対象としたMike Hadlow's implementation of generic repositories(linqからsqlへのフレーバ)を解決しています。動作するコンテナの構成:ユニティコンストラクタインジェクションがレポジトリを期待どおりに解決しない

container.RegisterType<IConnectionStringProvider, HistoryConnectionProvider>(new TransientLifetimeManager()) 
     .RegisterType<IConnectionStringProvider, MetaConnectionProvider>("meta", new TransientLifetimeManager()) 
     .RegisterType<IDataContextProvider, DataContextProvider>(new TransientLifetimeManager()) 
     .RegisterType<IDataContextProvider, DataContextProvider>("meta", new TransientLifetimeManager(), new InjectionConstructor(new ResolvedParameter<IConnectionStringProvider>("meta"))) 
     // this registration of Repository<> resolves the history database by default 
     .RegisterType(typeof(IRepository<>), typeof(Repository<>), new TransientLifetimeManager()); 
     // anything not targeting this database has to be declared 
     .RegisterType<IRepository<SpecificType>, Repository<SpecificType>>(new TransientLifetimeManager(), new InjectionConstructor(new ResolvedParameter<DataContextProvider>("meta"))); 

これは不必要に冗長なようです。私は現在、さまざまなアプローチを試みています。

IConnectionStringProvider historyConnectionProvider = new ConnectionProvider(connections.HistoryConnectionString); 
IConnectionStringProvider metaConnectionProvider = new ConnectionProvider(connections.MetaConnectionString); 

container.RegisterType<IDataContextProvider, DataContextProvider>("history", new TransientLifetimeManager(), new InjectionConstructor(historyConnectionProvider)) 
     .RegisterType<IDataContextProvider, DataContextProvider>("meta", new TransientLifetimeManager(), new InjectionConstructor(metaConnectionProvider)) 
     .RegisterType(typeof(IHistoryRepository<>), typeof(Repository<>), new TransientLifetimeManager(), new InjectionConstructor(new ResolvedParameter<IDataContextProvider>("history"))) 
     .RegisterType(typeof(IMetaRepository<>), typeof(Repository<>), new TransientLifetimeManager(), new InjectionConstructor(new ResolvedParameter<IDataContextProvider>("meta"))); 

残念ながら、これは機能しません。結果は、IDataContextProviderの最後の型が登録されて、すべてのタイプのリポジトリに注入されることになります。助けを前にありがとう。

答えて

0

元の質問へのソリューション

Unityはユニークなタイプ、などのインタフェースを必要としていました。コンストラクタインジェクションがこれを処理しなかった理由はまだ分かりません。これは動作します:

// where IMetaRepository<T> and MetaRepository<T> both are derived place holders 
container.RegisterType(typeof(IMetaRepository<>), typeof(MetaRepository<>), new TransientLifetimeManager()); 

残念ながら、これは私がと幸せではなかった消費クラスが自分のデータがどこから来ているの知識を必要とする状況を、設定します。

よりよい設計

私は(そう、これは私のモデルは、特定のインターフェイスに付着させる除外)生成された私のdbmlsを残したかったので、私はちょうど、設計者が発生させる、異なるサブフォルダにそれらを投げましたデータベースごとに異なる名前空間。

その後、私のリポジトリの実装では、私は次のようでした:

public Repository(IConnections connections) 
{ 
    T type = new T(); 
    var ns = type.GetType().Namespace; 
    if (ns == "Project.Common.DAL.History") 
    { 
    _dataContext = new DataContext(connections.HistoryConnectionString); 
    } 
    else if (ns == "Project.Common.DAL.Transaction") 
    { 
    _dataContext = new DataContext(connections.TransactionConnectionString); 
    } 
    else 
    { 
    _dataContext = new DataContext(connections.MetaConnectionString); 
    } 
} 

を私はこの過去の一歩は、私のために名前空間をチェックし、注入に戻るには、統一のためのカスタム型のレゾルバを構築することだと思いますデータ・コンテキスト(これは作業単位を実装する前に必要です)。私は誰かがより良い解決策を持っている場合に備えてこれを答えとしてマークするつもりはありません。

0

ダニエル、別の登録の名前を付ける目的は何ですか?すでにデータベースごとに別々のインターフェースを用意しているので、名前を付ける必要はありません。私は誤解される可能性があります。さらに、2番目の例では、リポジトリがIMetaとIHistoryの両方のインタフェースを満たすことができる場合は、両者の違いは何かという疑問があります。

あなたが望むものを達成するためにどのようにコード例が与えられていれば、実際にはそれほど冗長ではない最初の例と非常によく似ています。

+0

Hey Rob、レスポンスありがとうございます。メタデータベースを対象とする50のリポジトリを取得した後、ヒストリをターゲットに設定する際のデフォルトの動作に対する例外は、かなりの量のコードになります。毎回例外を作成するのではなく、IHistoryRepositoryを宣言してそのデータベースを対象とするレポを取得することが容易になりました。 IDataContextProvidersの名前を付ける限り、これらのIDataContextProvidersのライフタイムをコンテナ(最終的にWebリクエストごと)で処理するようにしたいので、登録する必要があると感じました。あなたは違いがないということは間違いありません。 –

関連する問題