将数据上下文从工作单元传递到存储库

发布于 2024-12-11 14:49:25 字数 1807 浏览 0 评论 0原文

我使用存储库进行数据访问已经有一段时间了,但从未成功实现任何类似于工作单元模式的东西。我已经开始了一个使用 RavenDB 和 ASP.NET MVC 进行自学的新项目(理论上,细节应该是微不足道的),并且正在寻求建立一种包装业务事务的好方法(不是 web请求)在他们自己的工作单位中,但这样做有些困难。

下面的代码片段是我希望看到的:

public class UserService : IUserService
    {
        private readonly IRepository<User> _userRepository;
        private readonly IRepository<Role> _roleRepository;

        public UserService(
               IRepository<User> userRepository, 
               IRepository<Role> roleRepository)
        {
            _userRepository = userRepository;
            _roleRepository = roleRepository;
        }

        public void Register(User user)
        {
            using (var session = UnitOfWork.Begin())
            {
                _userRepository.Create(user);
                _roleRepository.AddToRole(user, Role.Public);
                session.Commit();
            }
        }
    }

我对工作单元界面的第一次尝试看起来像这样:

 public interface IUnitOfWork : IDisposable
    {
        void Commit();
    }

    public class UnitOfWork : IUnitOfWork
    {
        private readonly IDocumentSession _session;

        public UnitOfWork(IDocumentStore documentStore)
        {
            _session = documentStore.OpenSession("http://from:config");
        }

        public void Commit()
        {
            _session.SaveChanges();
        }

        public static IUnitOfWork Begin()
        {
            return IoC.GetInstance<IUnitOfWork>();
        }

        public void Dispose()
        {
            _session.Dispose();
        }
  }

我遇到的困难是存储库对数据库会话的访问。正如我所提到的,我想将业务交易包装在它们自己的单元中;我也不热衷于将会话/上下文传递到每个方法中,并且我见过的大多数其他解决方案都使用静态方法和/或存储在 Web 会话之类的内容中。这一切都让我有些不舒服;对于整个工作单元概念,我是否遗漏了一些关键的东西?

I've been using repositories for data access for some time now but have never successfully implemented anything resembling the Unit of Work pattern. I've started a new project for self-education using RavenDB and ASP.NET MVC (details that should be trivial, in theory) and am looking to establish a good way to wrap business transactions (not web requests) in their own units of work, but am having some difficulty doing so.

The following code snippet is what I'd like to see:

public class UserService : IUserService
    {
        private readonly IRepository<User> _userRepository;
        private readonly IRepository<Role> _roleRepository;

        public UserService(
               IRepository<User> userRepository, 
               IRepository<Role> roleRepository)
        {
            _userRepository = userRepository;
            _roleRepository = roleRepository;
        }

        public void Register(User user)
        {
            using (var session = UnitOfWork.Begin())
            {
                _userRepository.Create(user);
                _roleRepository.AddToRole(user, Role.Public);
                session.Commit();
            }
        }
    }

My first stab at a unit of work interface looks something like this:

 public interface IUnitOfWork : IDisposable
    {
        void Commit();
    }

    public class UnitOfWork : IUnitOfWork
    {
        private readonly IDocumentSession _session;

        public UnitOfWork(IDocumentStore documentStore)
        {
            _session = documentStore.OpenSession("http://from:config");
        }

        public void Commit()
        {
            _session.SaveChanges();
        }

        public static IUnitOfWork Begin()
        {
            return IoC.GetInstance<IUnitOfWork>();
        }

        public void Dispose()
        {
            _session.Dispose();
        }
  }

Where I'm stuck is the repositories' access to the database session. As I mentioned, I'd like to wrap business transactions in their own units; I'm also not keen on passing the session / context into each method, and most other solutions I've seen use static methods and / or storage in something like the web session. All of these make me a little uncomfortable; is there something key that I'm missing to this whole Unit of Work concept?

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

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

发布评论

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

评论(2

梅窗月明清似水 2024-12-18 14:49:25

我不喜欢 TransactionScope 概念,并且需要进一步研究和改进。讨论使我相信我想做的事情根本不可行。

最后,UnitOfWork 上下文中的存储库需要(明确)了解 UnitOfWork。我还没有决定走哪条路,但我将做以下其中一项:

using (var session = UnitOfWork.Begin())
            {
                _userRepository.Use(session).Create(user);
                _roleRepository.Use(session).AddToRole(user, Role.Public);
                session.Commit();
            }

或者

using (var session = UnitOfWork.Begin())
            {
                session.Get<IUserRepository>().Create(user);
                session.Get<IRoleRepository>().AddToRole(user, Role.Public);
                session.Commit();
            }

我对这两种方法都不感兴趣;我会将其标记为答案,直到收到更好的建议。

I'm not fond of the TransactionScope concept, and further research & discussion has led me to believe that what I am trying to do is simply not feasible.

In the end, the repositories within the UnitOfWork's context need to (explicitly) know about the UnitOfWork. I haven't settled on which way to go just yet, but I'm going to do something like one of the following:

using (var session = UnitOfWork.Begin())
            {
                _userRepository.Use(session).Create(user);
                _roleRepository.Use(session).AddToRole(user, Role.Public);
                session.Commit();
            }

or

using (var session = UnitOfWork.Begin())
            {
                session.Get<IUserRepository>().Create(user);
                session.Get<IRoleRepository>().AddToRole(user, Role.Public);
                session.Commit();
            }

I'm not crazy about either approach; I'll mark this as the answer until I receive a better suggestion.

暖阳 2024-12-18 14:49:25

Julia Lerman 有一些使用实体框架的工作单元的精彩示例。

在实体框架中,它在上下文中受到支持,因此很容易实现工作单元。
我看到的主要问题是如何管理订单。
示例:表 A 和表 B

表 B 具有表 A 的外键。
您的工作单元必须知道如何排序,否则会出错。
我会选择像 Nhibernate 或 EF 这样的 OR/M。
它应该会让事情变得更容易。

Julia Lerman has some great examples of the Unit of Work using Entity Framework.

In entity framework it is supported in the context so it is very easy to implement a unit of work.
The main problem I would see is how do you manage the order.
Example: Table A and Table B

Table B has a foreign key to Table A.
Your unit of work would have to know to order otherwise it would error out.
I would just go with an OR/M like Nhibernate or EF.
It should make like a lot easier.

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