Simple Injector Dependency Injection フレームワークの速度に感銘を受けたため、それに切り替えようとしています。
private static void RegisterServices(Container container)
{
container.RegisterPerWebRequest<IDbContext, DbContext1>();
////container.RegisterPerWebRequest<IDbContext, DbContext2>();
container.RegisterPerWebRequest<IUnitOfWork, UnitOfWork>();
container.RegisterPerWebRequest<IColourRepository, ColourRepository>();
ここで、DbContext1 と DbContext2 は BaseDbContext クラスから継承します
public class BaseDbContext<TContext> : DbContext, IDbContext where TContext : DbContext
かなり単純な IDbContext インターフェイスを実装します (SO で提供される多くのものと同様)。
public interface IDbContext
{
IQueryable<TEntity> Find<TEntity>() where TEntity : class;
DbSet<TEntity> Set<TEntity>() where TEntity : class;
int SaveChanges();
void Dispose();
}
DbContext クラスを 1 つだけ使用すると、正常に動作します。リポジトリが挿入されたり、データがプルされたりします。
ただし、コードファーストの DbContext には数百のクラスが含まれるため、それぞれに少数の DbSet を含む境界付けられたコンテキストを使用したいと思います ( Shrink EF Models with DDD Bounded Contexts )。
private static void RegisterServices(Container container)
{
container.RegisterPerWebRequest<IDbContext, DbContext1>();
container.RegisterPerWebRequest<IDbContext, DbContext2>();
container.RegisterPerWebRequest<IUnitOfWork, UnitOfWork>();
container.RegisterPerWebRequest<IColourRepository, ColourRepository>();
次に、例外が発生します。
System.InvalidOperationException がユーザー コードによって処理されませんでした。現在の登録を上書きできるようにするには、Container.Options.AllowOverridingRegistrations を true に設定してください。Source=SimpleInjector StackTrace: at SimpleInjector.Container.ThrowWhenTypeAlreadyRegistered(Type 型) at SimpleInjector.Container.AddRegistration(Type serviceType, 登録登録) at SimpleInjector.Container.Register[TService,TImplementation](ライフスタイル, String serviceTypeParamName, String implementationTypeParamName) at SimpleInjector.Container.Register[TService,TImplementation](ライフスタイル・ライフスタイル) を SimpleInjector に登録します。
私が提案に従えば:
container.Options.AllowOverridingRegistrations = true;
次に、DbContext2 が DbContext1 をオーバーライドしているように見えます。たとえば、DbSet "Colour" は DbContext1 にあり、アクセスできなくなりました。
Additional information: The entity type Colour is not part of the model for the current context.
Simple Injector とバインドされた DbContext を一緒に使用するにはどうすればよいですか?
[アップデート]
DbContexts はコントローラで直接使用されるのではなく、Simple Injector がコンストラクタで初期化できるリポジトリの依存関係です。
public class ColoursController : ApiController
{
private readonly IColourRepository _repository;
private readonly ModelFactory _modelFactory;
public ColoursController(IColourRepository repository)
{
_repository = repository;
_modelFactory = new ModelFactory();
}
どこ
public class ColourRepository : Repository<Colour>, IColourRepository
{
public ColourRepository(IDbContext context) : base(context) { }
ColourRepository は DbContext1 の具体的な実装を想定していますが、他のリポジトリでは DbContext2 が必要になる場合があります (エンティティのセットが異なります)。
DbContext1 と DbContext2 の両方に IDbContext インターフェイス (または基本型) を使用できない理由がわかりません。
Unity でできること:
container.RegisterType<IDbContext, NorthwindContext>(new PerRequestLifetimeManager(), "NorthwindContext");
container.RegisterType<IDbContext, NorthwindCustomerContext>(new PerRequestLifetimeManager(), "NorthwindCustomerContext");
ニンジェクトはそれを行うことができます。
Simple Injector は CompositeLogger について言及しています。