我正在尝试切换到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 类,它可以正常工作 - 存储库被注入、数据被拉取等。
但是,我还想使用每个 DbSet 数量较少的有界上下文(Shrink EF Models with DDD Bounded Contexts),因为我的 Code-First DbContext 否则将包含数百个类
private static void RegisterServices(Container container)
{
container.RegisterPerWebRequest<IDbContext, DbContext1>();
container.RegisterPerWebRequest<IDbContext, DbContext2>();
container.RegisterPerWebRequest<IUnitOfWork, UnitOfWork>();
container.RegisterPerWebRequest<IColourRepository, ColourRepository>();
然后我得到一个例外:
System.InvalidOperationException 未由用户代码处理 HResult=-2146233079 Message=Type IDbContext 已注册,并且容器当前未配置为允许覆盖注册。要允许覆盖当前注册,请将 Container.Options.AllowOverridingRegistrations 设置为 true。Source=SimpleInjector StackTrace: 在 SimpleInjector.Container.ThrowWhenTypeAlreadyRegistered(Type type) 在 SimpleInjector.Container.AddRegistration(Type serviceType, Registration registration) 在 SimpleInjector.Container.Register[TService,TImplementation](Lifestyle Lifestyle, 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 和 bounded DbContexts?
[更新]
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");
Ninject 可以做到。
Simple Injector 提到了 CompositeLogger - 也许那个可以解决问题?