現在、データアクセス戦略としてEntity Framework 5(.net 4)を使用するn層ソリューションを設計していますが、依存性注入を組み込んでテスト可能/柔軟にする方法について懸念しています。
私の現在のソリューションレイアウトは次のとおりです(私のソリューションはアルカトラズと呼ばれます)。
Alcatraz.WebUI:フロントエンドユーザーインターフェイスであるasp.net Webformプロジェクトは、プロジェクトAlcatraz.BusinessおよびAlcatraz.Data.Models。
Alcatraz.Business:クラスライブラリプロジェクト、ビジネスロジックを含み、プロジェクトを参照Alcatraz.Data.Access、Alcatraz.Data.Models
Alcatraz.Data.Access:クラスライブラリプロジェクト、住宅AlcatrazModel.edmxおよびAlcatrazEntities
DbContext、プロジェクトAlcatraz.Data.Models。
Alcatraz.Data.Models:クラスライブラリプロジェクト。参照なしで、アルカトラズモデルのPOCOを含みます。
このソリューションがどのように機能するかについての私のビジョンは、web-uiがビジネスライブラリ内でリポジトリをインスタンス化し、このリポジトリが(AlcatrazEntities
インスタンスではなく)接続文字列の(コンストラクタを介して)依存関係を持つことです。 web-uiはデータベース接続文字列を知っていますが、エンティティフレームワーク接続文字列であることは知りませんでした。
ビジネスプロジェクト:
public class InmateRepository : IInmateRepository
{
private string _connectionString;
public InmateRepository(string connectionString)
{
if (connectionString == null)
{
throw new ArgumentNullException("connectionString");
}
EntityConnectionStringBuilder connectionBuilder = new EntityConnectionStringBuilder();
connectionBuilder.Metadata = "res://*/AlcatrazModel.csdl|res://*/AlcatrazModel.ssdl|res://*/AlcatrazModel.msl";
connectionBuilder.Provider = "System.Data.SqlClient";
connectionBuilder.ProviderConnectionString = connectionString;
_connectionString = connectionBuilder.ToString();
}
public IQueryable<Inmate> GetAllInmates()
{
AlcatrazEntities ents = new AlcatrazEntities(_connectionString);
return ents.Inmates;
}
}
Web UIで:
IInmateRepository inmateRepo = new InmateRepository(@"data source=MATTHEW-PC\SQLEXPRESS;initial catalog=Alcatraz;integrated security=True;");
List<Inmate> deathRowInmates = inmateRepo.GetAllInmates().Where(i => i.OnDeathRow).ToList();
このデザインに関していくつか質問があります。
この設計は、Entity Frameworks機能の点でも意味がありますか? Entityフレームワークは既に作業単位パターンを使用していると聞きましたが、不必要に抽象の別のレイヤーを追加しているだけですか?
私のWeb UIがEntity Frameworkと直接通信する(またはそれを参照する)ことはしたくありません。将来的には同じビジネスレイヤーを使用する複数のプロジェクトがあるため、すべてのデータベースアクセスがビジネスレイヤーを通過するようにしたい(Webサービス、Windowsアプリケーションなど)そして、ビジネスロジックを1つの中央領域に配置することで、保守/更新を簡単に行えるようにしたいと考えています。これはこれを達成するための適切な方法ですか?
ビジネス層にリポジトリを含める必要がありますか、それともアクセス層内に含める必要がありますか?それらがどこにあるかが問題ない場合、接続文字列を渡すことは仮定するのに良い依存関係ですか?
お読みいただきありがとうございます。
DIのやり方が間違っています。
まず、接続文字列はデータレイヤーに属します。または、web.configファイル内。
次に扱う抽象化は、接続文字列ではなくDbContextです。リポジトリは接続文字列を知らないはずです。ビジネスロジックはDbContextなどを認識しません。
UIには何も表示されず、EFに関連するものもインスタンス化されません。
あなたのポイントへの具体的な答え:
EFに精通するまでは、抽象化を追加しないでください。 UoW、クエリ、POCOの使用などの優れた抽象化がすでに追加されています。
DIを機能させるには、必要なすべてのコンポーネントを参照するコンポジションルートがあります。これは、WebUIプロジェクトにある場合とない場合があります。そうでない場合は、EFまたはその他のデータ関連技術を参照していないことを期待する必要があります。
ここで停止します。抽象化の上に抽象化を追加するのをやめます。直接の「素朴な」アーキテクチャから始めて、時間をかけて開発します。
抽象化は複雑さに対処するためのツールです。複雑さがないということは、(まだ)抽象化が必要ないことを意味します。
いくつかの簡単なコメント。私はおそらく個人的には接続文字列を渡さないでしょう。リポジトリ用のインターフェースを作成して試してみて、インターフェースを渡すだけの場合はどうでしょうか?リポジトリにIOWインターフェイスを実装または公開させます。
このように、リポジトリを実装するデータベースである必要はありません。それらは、メモリ内キャッシュ、または何でもかまいません。たぶん、あなたはある種の依存性注入フレームワークを使用してこれらをインスタンス化することもできますか?
だからあなたの質問のいくつかに答えて:
これらは、熟考するためのいくつかの考えにすぎません。