2011-09-26 73 views
0

我对UoW,Repository Pattern等非常熟悉,但在看到Entity Framework模式的各种实现时,我很好奇为什么每个人都有一个Save或Add方法他们的仓库。如果您使用的存储库,让你的对象的新实例,我会想象有人会已经实体框架/工作单元架构问题

public Customer GetNewCustomer() 
{ 
    Customer customer = new Customer(); 
    ... any initialization code here ... 
    _context.Customers.AddObject(customer); 
    return customer; 
} 

我知道在某些设计中,您可以简单地使用

 
Customer customer = new Customer(); 

和它不是任何地方连接在上下文中。然而,我是私人构造函数的粉丝,所以对于Customer对象有一个实例化的单一点。考虑到这一点,当使用UoW模式时,在储存库中永远不会有添加/保存方法是有意义的,并且仅在IUnitOfWork接口上具有此功能?

回答

1

当我遵循Java中的Spring成语时,工作单元(和事务)与服务相关联。他们使用模型和持久对象来完成请求。事务使用方面进行了划分。

我不知道.NET是否遵循类似的想法,但它是值得探讨的。拥有基于接口的POCO服务并让他们自己进行交易。

+0

在.NET中,'可以'以同样的方式发生。除了明确的代码事务使用外,方面还可以用于EF环境中的内置处理。我对UoW模式并不陌生,但它与DbContext与实体框架如何作为它的一部分一起工作,在某种意义上我正在寻找意见(谢谢,虽然!!) –

+0

.NET有Spring.NET - 它不像Java中的Spring那么强大,但它可以以AoP方式处理事务。问题是它不容易与Entity框架相结合。你将不得不移动到NHibernate。另一个问题是,你应该有一个已经在你的团队中进行过这种方式的人,否则这将是非常痛苦的经历。 –

1

我不认为你的解决方案是正确的。这将增加空客户到当前的工作单元。这意味着,如果后来的代码决定不通过当前的工作单元来节省客户,那么以后的代码将会很困难。

存储库有保存实体的方法是很常见的。要结合在领域驱动设计

  • 对象工厂

库的职责是检索或存储实体使用的两种模式。对象工厂的职责是处理实体构建。

Btw。如果存储库不是实体(这将非常糟糕),那么实体的私有构造函数将无法在您的存储库中访问。

+0

我应该显示上面的Customer.NewCustomer()。我认为上下文让我对它的最佳实现感到困惑,因为它包含了一些自己的UoW。在这种情况下,通过为您的C(rud)存储库,为您的对象需要一个位置,在这种情况下创建。有人可能会说'如果我需要一个独立的客户对象怎么办',那么你可以使用工厂,但这种情况下确保它的上下文的一部分,不需要添加。一个纯粹的UoW会有.Add,但这里使用上下文也有它自己的对象跟踪,因此有点模糊。 –

1

......不会是有意义的永远不会有一个附加/使用UOW模式时,在 库保存方法,只有拥有IUnitOfWork接口上此功能 ?

是的我认为只有IUnitOfWork界面上有Save方法才有意义。但是,我不再使用EF的存储库模式。相反,我现在使用thesevariations的命令&查询模式。如果你仔细想一下,EF DbContext实际上是做了三件事情:1)它作为你的知识库读取实体状态,2)作为你的变种实体状态库,3)作为UnitOfWork用于跟踪多个变化并将它们组合成单个事务以保持状态突变。

那么,为什么不把这3个责任分成3个不同的界面呢?

public interface IUnitOfWork 
{ 
    int SaveChanges(); 
} 

public interface ICommandEntities : IQueryEntities 
{ 
    void Create(Entity entity); 
    void Update(Entity entity); 
    void Purge(Entity entity); 
} 

public interface IQueryEntities 
{ 
    IQueryable<AggregateRoot1> AggregateRoot1s { get; } 
    IQueryable<AggregateRoot2> AggregateRoot2s { get; } 
    IQUeryable<AggregateRootN> AggregateRootNs { get; } 

    IQueryable<TEntity> EagerLoad<TEntity>(IQueryable<TEntity> query, 
     Expression<Func<TEntity, object>> expression) 
     where TEntity : Entity; 
} 

然后,您可以在DbContext类上实现这3个接口。这使接口保持良好和分离状态,并让您只依赖注入您需要的DbContext的方法。

例如,您的域名应该是持久性无知的,对吗?在这种情况下,请勿给IUnitOfWork界面上的任何域类依赖项。相反,请处理IoC组成根(或MVC操作筛选器)中的IUnitOfWork。然后,您的查询和命令处理程序仅处理ICommandEntities和IQueryEntities接口。

+0

曾经有人提出CQRS在.net之外没有任何地方完成,而其他强大的架构实践已经并且已经有一段时间了。这让我想起了一点,但肯定更'好奇'为什么 –

+0

@ AdamTuliper-MSFT,CQRS确实是在.net之外完成的:http://www.infoq.com/news/2014/08/reactive -cqrs-application?utm_campaign = infoq_content&utm_source = infoq&utm_medium = feed&utm_term = global – danludwig

+0

当然,但这也是两年多前:)很多顶级点击仍然是基于.NET的,但很高兴看到_some_在.net之外提及它(尽管那篇文章是技术不可知的IIRC) –