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

发布于 2024-12-28 16:47:57 字数 1341 浏览 1 评论 0原文

我刚刚开始阅读有关使用存储库和工作单元模式的内容。我目前正在尝试在 ASP.NET Web 表单应用程序中将它与实体框架一起使用。然而,我确实有一个问题,我不确定是否能够以简单的方式解释。

据我了解,工作单元用于封装业务事务。从示例中我看到 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()。假设我想在 businessMethod2() 中使用 businessMethod1() ,这将是最佳实践。我想共享工作单元,那么我应该将其作为参数传递吗?即,将上面提到的方法更改为

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 实例,并由所有业务方法共享。根据新请求,会创建不同的实例。使用单例 uow 意味着我不必将其传递给我的任何业务方法,并且可以同时与我的所有业务方法共享它。

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

I have just started reading up on using the repository and unit of work patterns. I am currently trying to use it with Entity Framework in an asp.net web forms application. I do however have a question which I am not sure if I would be able to explain in an easy way.

From what I understand a unit of work is used to encapsulate a business transaction. From the examples I have seen a uow is used in the following manner

 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
 }

Now suppose I have a businessMethod2() which is similar to the method described above. Suppose I want to use businessMethod1() from within businessMethod2() what would be the best practice. I would want to share the unit of work so should I pass it as an argument? i.e change the method mentioned above to

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.         
}

Is this a proper way of working with this?

I was thinking a better way would be to use a singleton uow. On every page request a new instance of the uow is created and is shared by all the business methods. On a new request a different instance is created. Using a singleton uow would mean i wont have to pass it to any of my business methods and can at the same time share it b/w all my business methods.

Are there any drawbacks of doing this? Also is there a better way to implement this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

客…行舟 2025-01-04 16:47:57

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

public class MyBusinessService
{

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

   public void businessMethod1()
   {
   }

   public void businessMethod1()
   {
   }
}

有许多流行的 DI 框架。选择您认为对您有用的内容。

One way to solve this problem is to use Dependency Injection. Usually constructor injection is used along side a single point of entry to resolve dependencies.

public class MyBusinessService
{

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

   public void businessMethod1()
   {
   }

   public void businessMethod1()
   {
   }
}

There are many popular DI frameworks out there. Pick what you think works for you.

蘑菇王子 2025-01-04 16:47:57

这是关于 UoW 的使用。如果您将 UoW 的使用放入 BusinessMethod1 中,您就是说它是顶级业务抽象(业务外观)。它可能不应该被其他业务操作使用,因为它会破坏其“顶层”。因此,如果您需要在另一个 BusinessMethod2 中使用 BusinessMethod1 中的逻辑,那么添加有关 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提到的方法,但如果您的method2想要从method1调用某些内容,则此重构仍然适用。

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

This is about usage of UoW. If you place usage of UoW into BusinessMethod1 you are saying that it is top level business abstraction (business facade). It should probably not be used by other business operation because it would break its "top level". So if you need to use the logic from BusinessMethod1 in another BusinessMethod2 it is not correct approach to add logic making decision about UoW existence - that breaks separation of concerns. BusinessMethod should handle your application logic not UoW creation. Simplest solution is to refactor your BusinessMethod1 and expose shared functionality as a new method without any dependency on 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();
}

Sure this is only very simple example because your methods still don't follow separation of concerns - they do both logic and object creation. You should handle UoW and repositories creation elsewhere and pass created objects inside. You can use approach mentioned by @Eranga but this refactoring will be still applicable if your method2 wants to call something from method1.

This refactoring approach can be modeled also as low level business services and business facade but it is needed only in big projects. In small projects you can also move interaction with UoW to your "controller" (probably code behind in web forms) because the controller drives application logic and it knows what business methods it wants to call in single unit of work.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文