MVC アプリケーションで Ninject を使用しており、Unit of Work リポジトリ パターンを実装しようとしています。
具体的には、一般的な IUnitOfWork インターフェイスを定義しました。次に、このインターフェイスのインスタンスを他の (ビジネス ロジック クラス) のコンストラクターで使用したいと考えています。これが私のコントローラーの始まりです...
public class CompanyController : Controller
{
private readonly IUnitOfWork UnitOfWork;
private readonly ICompanyService CompanyDb;
private readonly IEmployeeService EmployeeDb;
public CompanyController(IUnitOfWork unitOfWork)
: base()
{
this.UnitOfWork = unitOfWork;
// This following construction is the problem...
this.CompanyDb = new ICompanyService(this.UnitOfWork);
this.EmpoloyeeDb = new IEmployeeService(this.UnitOfWork);
}
// Rest of Controller implementation
}
コントローラー コンストラクターは正しく動作しますが、さまざまなビジネス ロジック クラスを構築するクリーンな方法を見つけて、UnitOfWork オブジェクト内のリポジトリを参照できるようにしたいと考えています。
問題は、インターフェイスから新しいビジネス ロジック オブジェクトをインスタンス化できないことです。つまり、次のコードが失敗します。
this.CompanyDb = new ICompanyService(this.UnitOfWork);
ICompanyService インターフェイスを具体的な実装に「配線」するものは何もないためです。私がやりたいことは、DI (Ninject) を使用して、物理クラスのコンストラクターが次のようになる ICompanyService のインスタンスを作成することです。
public class CompanyService : ICompanyService {
private readonly UnitOfWork db;
public CompanyService(IUnitOfWork unitOfWork) {
this.db = unitOfWork as UnitOfWork;
}
}
最終的な解決策 Joshscorp と Dbaseman からの提案 (ありがとう) に加えて、次のようにコードを構成しました。
public class CompanyService : ICompanyService {
private readonly UnitOfWork db;
public CompanyService(IUnitOfWork unitOfWork) {
this.db = unitOfWork as UnitOfWork;
}
// Rest of implementation
}
public class CodeFirstController : Controller {
private readonly IUnitOfWork UnitOfWork;
private readonly ICompanyService CompanyDb;
private readonly IEmployeeService EmployeeDb;
public CodeFirstController(
IUnitOfWork unitOfWork,
ICompanyService companyDb,
IEmployeeService employeeDb
) : base() {
this.UnitOfWork = unitOfWork;
this.CompanyDb = companyDb;
this.EmployeeDb = employeeDb;
}
// Rest of implementation
}
Ninject モジュールは次のとおりです。
public class CodeFirstModule : NinjectModule {
public override void Load() {
string connectionString = ConfigurationManager
.ConnectionStrings["CompanyConnection"]
.ConnectionString;
Bind<CodeFirst.DAL.IUnitOfWork>()
.To<CodeFirst.DAL.EntityFramework.UnitOfWork>()
.InRequestScope()
.WithConstructorArgument("connectionString", connectionString);
Bind<CodeFirst.DAL.ICompanyService>()
.To<CodeFirst.DAL.EntityFramework.CompanyService>()
.InRequestScope();
Bind<CodeFirst.DAL.IEmployeeService>()
.To<CodeFirst.DAL.EntityFramework.EmployeeService>()
.InRequestScope();
}
}
IUnitOfWork バインディングの 'InRequestScope()' メソッドは、UnitOfWork クラスの同じインスタンスが依存クラス CompanyService および EmployeeService のコンストラクターで使用されることを保証します。
これはまさに私が探していたもの、つまり依存サービス クラスによって参照される IUnitOfWork オブジェクトの単一インスタンスを実現します。