3

我只是有一个简单的问题。我试图在我的 asp.net MVC 项目中使用 Unity。我在使用带有 EF 上下文的工作单元模式时遇到了一个问题。

假设我在构造函数中注入了 uow,但控制器中有 4 或 5 个操作需要UnitOfWork在 using 语句中使用。这行不通!因为 Id 必须
new UnitOfWork() 在每个操作方法中执行一次。

我应该UnitOfWork在每个动作方法中注入一个吗?还是只进入构造函数?或者我什至应该注射这个!我面临的问题是我希望能够使用 Mock 数据对我的控制器进行单元测试,并且我只能在注入UnitOfWorkDBContext.

4

2 回答 2

3

而是注入工厂。这样您仍然可以实现关注点分离和松耦合,但您不会遇到使用语句的任何问题:

private IUnitOfWorkFactory factory;

public MyController(IUnitOfWorkFactory factory)
{
    this.factory = factory;
}

public ActionResult MyAction()
{
    using (var uow = factory.CreateUnitOfWork())
    {
        // ...
    }
}

编辑

这种方法的自然优势在于它的可配置性——你可以注册你喜欢的任何工厂来服务不同的控制器,并将其连接到组合根:

// Note: this isn't unity syntax, but I hope my point is clear
container.Register<ISessionFactory, ReusableSessionFactory>("Reusable");
container.Register<ISessionFactory, FreshSessionFactory>("Fresh");
container.Register<IController, LoginController>().With("Fresh");
container.Register<IController, HomeController>().With("Reusable");

现在,

  • LoginController将使用在每个请求下提供新会话的工厂
  • HomeController另一方面,将在其整个生命周期内重用同一个会话

值得注意的是,从控制器的角度来看,哪个工厂为会话提供服务是无关紧要的,因为它只是一个实现细节。这就是为什么我们将会话工厂依赖隐藏在抽象之后(本例中的接口),并在应用程序的根目录执行所有对象到依赖的绑定。

于 2013-01-14T12:58:43.463 回答
1

如果我理解正确,您只是希望能够使用起订量之类的东西来测试 UOW?

在这种情况下,为了获得良好的设计原则和适当的关注点分离,您应该为每个存储库类使用的数据库创建一个基本上下文。

然后,您应该为每个域模型实体创建一个存储库接口。然后您可以在单独的存储库中实现接口(这样您就可以实现 POCO 模型)

最后,您可以在域对象和操作方法之间创建一个服务层,或者只在操作方法中使用所需的存储库接口。

我这样回答是因为它取决于您的应用程序基础架构。如果您没有服务层,那么最佳做法是执行以下操作:

   public class AccountController : Controller
    {
        private readonly IAccountRepository _accountrepository;

        public AccountController(IAccountRepository repository)
        {
            _accountrepository = repository;
        }
}

我希望这有帮助。

于 2013-01-14T12:42:36.377 回答