我有一个带有 MVVM 的 WPF 应用程序。假设从 ViewModel 向下的对象组合如下所示:
MainViewModel
OrderManager
OrderRepository
EFContext
AnotherRepository
EFContext
UserManager
UserRepository
EFContext
我最初的方法是使用 EFContext 上的 .InCallScope() 和其他所有内容的 .InTransientScope() 将依赖项(从 ViewModelLocator)注入(inject)到我的 View 模型中。这导致能够跨多个业务层对象(管理器)执行“业务事务”,这些对象最终在下面共享相同的 Entity Framework 上下文。我会简单地 Commit() 在工作单元类型场景的末尾表示上下文。
这按预期工作,直到我意识到我不希望 View 模型级别的长期存在的 Entity Framework 上下文,描述的跨多个操作的数据完整性问题 HERE 。我想做一些类似于我的 Web 项目的事情,我在 Entity Framework 上下文中使用 .InRequestScope() 。在我的桌面应用程序中,我将定义一个工作单元,如果您愿意的话,它将充当业务事务,通常它将把所有内容包装在按钮单击或类似事件/命令中。看来使用 Ninject 的 ActivationBlock 可以帮我做到这一点。
internal static class Global
{
public static ActivationBlock GetNinjectUoW()
{
//assume that NinjectSingleton is a static reference to the kernel configured with the necessary modules/bindings
return new ActivationBlock(NinjectSingleton.Instance.Kernel);
}
}
在我的代码中,我打算这样使用它:
//Inside a method that is raised by a WPF Button Command ...
using (ActivationBlock uow = Global.GetNinjectUoW())
{
OrderManager orderManager = uow.Get<OrderManager>();
UserManager userManager = uow.Get<UserManager>();
Order order = orderManager.GetById(1);
UserManager.AddOrder(order);
....
UserManager.SaveChanges();
}
问题:
- 对我来说,这似乎复制了我在网络上开展业务的方式,这种方法是否存在我所错过的本质上的错误?
- 我是否正确理解使用激活 block 的所有 .Get<> 调用都会生成该 block 本地的“单例”?我的意思是,无论我请求 OrderManager 多少次,它总是会在 block 内给我相同的一个。如果 OrderManager 和 UserManager 在下面组成相同的存储库(例如 SpecialRepository),则两者都将指向存储库的同一实例,并且显然下面的所有存储库共享 Entity Framework 上下文的相同实例。
最佳答案
这两个问题都可以回答"is":
- 是的 - 这是您不应该做的服务地点
- 是的,您理解正确
关于wpf - Ninject ActivationBlock 作为工作单元,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8671211/