【发布时间】:2013-05-03 23:00:36
【问题描述】:
我的工作单元和存储库的实现可能是这里问题的根源。但考虑到我到处寻找工作单元 实现我看到了一个不同的实现,我确信 Ninject 有办法解决它。
所以我将IRepository<T> 的实现注入到我的“工作单元”的构造函数中。
_kernel.Bind<IRepository<SomeType1>>().To<RepoOfSomeType1>().WhenInjectedInto<IMyUoWFactory>();
_kernel.Bind<IRepository<SomeType2>>().To<RepoOfSomeType2>().WhenInjectedInto<IMyUoWFactory>();
...
我已将内核设置为在 singleton 范围 中实例化 DataContext,我认为这意味着每当我注入此 DataContext 的相同实例需要它:
_kernel.Bind<DataContext>().ToConstructor(arg => new MyDataContext(arg.Inject<string>()))
.InSingletonScope() // pass same instance to all repositories?
("connection", _someConnectionString);
我发现的问题是,每个存储库似乎都有自己的实例,而且工作单元也有自己的实例 - 因此当我尝试提交事务时遇到异常(关于交叉-上下文事务)。
最重要的是,在某些特定情况下,我需要连接字符串是动态的,以便工作单元可以处理用户选择的数据库 - 因此“需要”工厂。
结果是我有 1 个连接每个存储库 加上 1 个连接每个工作单元,这违背了 UoW 的目的(即事务性数据操作),以及所有我认为,这种开销会导致严重的性能问题(在 3-4 小时内运行 +/- 200,000 个小数据操作!!)。
这就是我创建工作单元实例的方式;我希望能够在其中注入存储库实现,但仍然能够使用用户要求的连接字符串:
public MyUoWFactory(IRepository<Type1> type1repo, IRepository<Type2> type2repo,
IRepository<Type3> type3repo, IRepository<Type4> type4repo,
IRepository<Type5> type5repo, IRepository<Type6> type6repo)
{
_type1Repository = type1repo;
_type2Repository = type2repo;
_type3Repository = type3repo;
_type4Repository = type4repo;
_type5Repository = type5repo;
_type6Repository = type6repo;
}
public IUnitOfWork Create(string userSelectedConnectionString)
{
return new MyUoW(new MyDataContext(userSelectedConnectionString),
_type1Repository, _type2Repository, _type3Repository,
_type4Repository, _type5Repository, _type6Repository);
}
使用我定义的内核绑定,这会导致存储库的 DataContext 指向内核指示的位置,而创建的 UoW 的 DataContext 指向用户请求的位置。
如何在不使用服务定位器的情况下实现这一目标?我需要存储库不是在应用程序启动时注入其 DataContext,而是在用户选择数据库之后。这是Ninject.Factory 发挥作用的地方吗?
【问题讨论】: