实体框架asp.net应用程序中的UOW和存储库

时间:2012-01-23 23:14:15

标签: asp.net entity-framework entity-framework-4 repository-pattern unit-of-work

我刚刚开始阅读使用存储库和工作单元模式。我目前正在尝试在asp.net Web表单应用程序中使用它与Entity Framework。但我有一个问题,我不确定我是否能够以一种简单的方式解释。

据我所知,工作单元用于封装业务事务。从我看到的示例中,以下列方式使用uow

 businessMethod1()
 {
    uow u = new uow(); //instantiate unit of work
    repository1 rep1 = new repository1(uow); //instantiate repository1 
    repository2 rep2 = new repository2(uow); //instantiate repository1 
    rep1.dowork();
    rep2.dowork();
    u.save(); //save the changes made to the database. (effectively saving changes made      
              //in both repository classes
 }

现在假设我有businessMethod2(),它与上述方法类似。假设我想在businessMethod1()内使用businessMethod2(),这将是最佳做法。我想分享工作单位,所以我应该把它作为一个论点来传递?即改变上述方法

businessMethod1(uow u)
{
    bool isNew = false;
    if (u == null)
    {
        u = new uow();
        isNew = true;
    }

    repository1 rep1 = new repository1(uow); //instantiate repository1 
    repository2 rep2 = new repository2(uow); //instantiate repository1 
    rep1.dowork();
    rep2.dowork();

    if (isNew)
      u.save(); //save the changes made to the database.         
}

这是一种正确的解决方法吗?

我在想更好的方法是使用单身哇。在每个页面请求中,都会创建一个新的uow实例,并由所有业务方法共享。在新请求中,将创建不同的实例。使用单身uow意味着我不必将其传递给我的任何商业方法,并且可以同时与我的所有业务方法共享它。

这样做有什么缺点吗?还有更好的方法来实现这个吗?

2 个答案:

答案 0 :(得分:2)

解决此问题的一种方法是使用依赖注入。通常,构造函数注入与单个入口点一起使用以解决依赖关系。

public class MyBusinessService
{

   public MyBusinessService(Repository1 repository1, Repository2, uow u)
   {
        // assign the params to fields
   }

   public void businessMethod1()
   {
   }

   public void businessMethod1()
   {
   }
}

有很多流行的DI框架。选择你认为适合你的东西。

答案 1 :(得分:2)

这是关于UoW的使用。如果您将UoW的使用放入BusinessMethod1,那么您说它是顶级业务抽象(业务外观)。它可能不应该被其他业务运营使用,因为它会破坏其“顶级”。因此,如果您需要在另一个BusinessMethod1中使用来自BusinessMethod2的逻辑,那么添加逻辑来决定UoW存在是不正确的方法 - 这会打破关注点的分离。 BusinessMethod应该处理您的应用程序逻辑而不是UoW创建。最简单的解决方案是重构您的BusinessMethod1并将共享功能公开为新方法,而不依赖于UoW:

public void BusinessMethod1()
{
    uow u = new uow(); 
    DoSomeWork();
    u.save(); 
}

private void DoSomeWork() 
{
    repository1 rep1 = new repository1(uow); //instantiate repository1 
    repository2 rep2 = new repository2(uow); //instantiate repository1 
    rep1.dowork();
    rep2.dowork();
}

当然这只是一个非常简单的例子,因为你的方法仍然没有遵循关注点的分离 - 它们同时创建逻辑和对象。您应该在其他地方处理UoW和存储库创建并在其中传递创建的对象。您可以使用@Eranga提到的方法,但如果您的方法2想要从method1调用某些内容,则此重构仍然适用。

这种重构方法也可以建模为低级业务服务和业务外观,但只在大型项目中才需要。在小型项目中,您还可以将与UoW的交互移动到“控制器”(可能是Web表单中的代码),因为控制器驱动应用程序逻辑,并且它知道在单个工作单元中要调用哪些业务方法。