工作单元实施

发布于 2024-10-16 04:16:56 字数 1760 浏览 2 评论 0原文

我已经能够实现一些很酷的工作单元来与实体框架一起使用。

我想出了..

public class UnitOfWork : IUnitOfWork
    {
        private Database _database;
        private IDatabaseFactory _databaseFactory;

        private DbTransaction transaction;

        public UnitOfWork(IDatabaseFactory databaseFactory)
        {
            _databaseFactory = databaseFactory;
            _database = Database;

            transaction = _database.Database.Connection.BeginTransaction();
        }

        public Database Database
        {
            get { return _database ?? (_database = _databaseFactory.Get()); }
        }

        public void Dispose()
        {
            try
            {
                _database.SaveChanges();
                transaction.Commit();
            }
            catch (Exception ex)
            {
                transaction.Rollback();
            }
        }
    }

我很确定现在每个人都嫉妒这个工作单元。 (开玩笑)

但是我在这个服务层有一些设计问题。

public class JournalService : IJournalService
    {
        IJournalRepository _journalRepository;

        public JournalService(IJournalRepository journalRepository)
        { 
            _journalRepository = journalRepository;
        }

        public void AjouterJournal(Journal j)
        {
           [B]using (IUnitOfWork uow = new UnitOfWork())[/B]
            {
                var journal = new Journal();
                journalRepository.AddJournal(journal);

            }
        }
    }

问题是工作单元需要数据库注入,所以我无法创建它的实例。我无法直接在服务层中提供工作单元,因为它没有意义,因为工作单元需要是一次性的。

而且因为我使用存储库来添加我的东西,所以不需要直接访问工作单元,因此当它被处置时,保存将自动发生。

我可以将 IDatabaseFactory 注入到我的服务层中,但想法是不在那里使用它。实际上服务层不应该知道它。

UnitOfWork 工厂怎么样?

关于如何解决这个问题有什么想法或建议吗?

谢谢。

Ive been able to implement a little cool unit of work to work with entity framework.

I came up with ..

public class UnitOfWork : IUnitOfWork
    {
        private Database _database;
        private IDatabaseFactory _databaseFactory;

        private DbTransaction transaction;

        public UnitOfWork(IDatabaseFactory databaseFactory)
        {
            _databaseFactory = databaseFactory;
            _database = Database;

            transaction = _database.Database.Connection.BeginTransaction();
        }

        public Database Database
        {
            get { return _database ?? (_database = _databaseFactory.Get()); }
        }

        public void Dispose()
        {
            try
            {
                _database.SaveChanges();
                transaction.Commit();
            }
            catch (Exception ex)
            {
                transaction.Rollback();
            }
        }
    }

I am pretty sure everyone is jealous of this unit of work now. (Kidding)

But i have a little design problem in this service layer.

public class JournalService : IJournalService
    {
        IJournalRepository _journalRepository;

        public JournalService(IJournalRepository journalRepository)
        { 
            _journalRepository = journalRepository;
        }

        public void AjouterJournal(Journal j)
        {
           [B]using (IUnitOfWork uow = new UnitOfWork())[/B]
            {
                var journal = new Journal();
                journalRepository.AddJournal(journal);

            }
        }
    }

The problem is the unit of work need a database injection so i cant create an instance of it. I can't provide an unit of work directly in the service layer because it would make no sense since the unit of work need to be disposable.

And because i use repository to add my stuff there no need to access the unit of work directly, the saving will occur automaticly when it will be disposed anyway.

I could inject the IDatabaseFactory in my service layer but the idea is to not use it there. Actually the service layer shouldnt know about it.

How about an UnitOfWork factory ?

Any ideas or suggestion on how i can fix this?

Thanks.

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

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

发布评论

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

评论(1

GRAY°灰色天空 2024-10-23 04:16:56

如果您想使用当前的架构,您应该将 UnitOfWork 注入到服务中。您的服务不会对 UnitOfWork 实现有内部(隐藏)依赖,并且可以更好地进行测试。它与面向对象架构的许多原则密切相关。

另一件事是该实现仅可用于简单的 CRUD 操作。在更复杂的服务中,您最终将得到多个操作的组合(可能来自多个服务),每个操作都将使用 UnitOfWork 进行操作。在一个业务操作中调用多个 SaveChanges(和事务)可能不是您通常想要的 - 在这种情况下,您只想从某个顶级服务或服务的调用者调用 SaveChanges 一次。典型场景是单个业务操作具有一个事务的一个工作单元,但您可以将许多服务操作作为该业务操作的一部分。

另一个含义是存储库的构建。他们可能需要访问数据库,不是吗?所以您可能已经将 UoW 注入存储库构造函数中。如果你这样做,你就可以完全避免 UoW 和基本服务之间的关系。

You should inject UnitOfWork into service if you want to use your current architecture. Your service will not have inner (hidden) dependency on UnitOfWork implementation and it will be better testable. It goes hand in hand with many principles of object oriented architecture.

Other thing is that this implementation is only usable for simple CRUD operations. In more complex services you will end up with composition of multiple operations (possibly from multipe services) which will each operate with UnitOfWork. Calling multiple SaveChanges (and transactions) in one business operation is probably not what you usually want - in such case you want to call SaveChanges only once from some top level service or from service's caller. Typical scenario is that single business operation has one unit of work with one transaction but you can do a lot of service's operations as part of this business operation.

Another implication is construction of your Repositories. They probably need access to Database, don't they? So you probably already inject UoW into repository constructor. If you do this you can avoid relation between UoW and basic services at all.

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