【问题标题】:Ninject ActivationBlock as Unit of WorkNinject ActivationBlock 作为工作单元
【发布时间】:2011-12-29 17:37:13
【问题描述】:

我有一个带有 MVVM 的 WPF 应用程序。假设从 ViewModel 向下的对象组合如下所示:

MainViewModel
    OrderManager
        OrderRepository
            EFContext
        AnotherRepository
            EFContext
    UserManager
        UserRepository
            EFContext

我最初的方法是使用 EFContext 上的 .InCallScope() 和 .InTransientScope() 将依赖项(来自 ViewModelLocator)注入到我的视图模型中。这导致能够跨多个业务层对象(管理器)执行“业务事务”,这些对象最终在下面共享相同的实体框架上下文。对于工作单元类型的场景,我会在最后简单地 Commit() 说上下文。

这按预期工作,直到我意识到我不希望在视图模型级别使用长期存在的实体框架上下文,描述了多个操作的数据完整性问题 HERE。我想做一些类似于我使用 .InRequestScope() 作为我的实体框架上下文的 Web 项目的事情。在我的桌面应用程序中,我将定义一个工作单元,如果您愿意,它将用作业务事务,通常它将所有内容都包含在按钮单击或类似事件/命令中。看来使用 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();
}

问题:

  1. 对我来说,这似乎复制了我在网络上开展业务的方式,我错过了这种方法是否存在固有的错误?
  2. 我是否正确理解所有使用激活块的 .Get 调用都会在该块本地产生“单例”?我的意思是,无论我请求 OrderManager 多少次,它总是会在块内给我同一个。如果 OrderManager 和 UserManager 在下面组成同一个存储库(例如 SpecialRepository),则两者都将指向存储库的同一个实例,显然,下面的所有存储库都共享同一个实体框架上下文实例。

【问题讨论】:

    标签: wpf entity-framework ninject ninject-2


    【解决方案1】:

    这两个问题都可以回答是:

    1. 是的 - 这是你不应该做的服务地点
    2. 是的,你理解正确

    【讨论】:

    • 是的,我知道它是,但是我没有看到任何其他选择。你有更好的建议吗?
    • 创建一个包含 using 块内容的类,使用工厂创建它的实例并将 EF 上下文放入 InCallScope。
    • 这意味着如果我的 WPF 窗口有 3 个 using 块,我将需要 3 个包含所需业务层类的类和每个集合的工厂。我知道它更干净,因为 ViewModel 不必直接与 ninject 交互,但我愿意接受这个打击以换取更高的生产力:) 我认为这是一个不错的权衡,因为业务层下层不会知道 ninject,只是视图模型。除非我误解了你的意思,如果我错了,请纠正我。
    【解决方案2】:

    Ninject.Extensions.UnitOfWork 中实现的适当工作单元范围解决了这个问题。

    设置:

    _kernel.Bind<IService>().To<Service>().InUnitOfWorkScope();
    

    用法:

    using(UnitOfWorkScope.Create()){
        // resolves, async/await, manual TPL ops, etc    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-08-11
      • 1970-01-01
      • 2011-11-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多