繁体   English   中英

在使用Entity Framework的分层架构中,我应该从BLL返回POCO类吗? (需要架构指导)

[英]In a layered architecture using Entity Framework, should I return POCO classes from the BLL? (Architecture guidance needed)

我可能读得太多了,而且还有一些信息过载。 所以我希望得到一些明确的指导。

根据我的收集,我可以使用VS2010的T4模板来生成与EF无直接关联的POCO类。 我将这些放在他们自己的项目中,而我的DAL将有一个ObjectContext派生类,对吧?

一旦我有了这些类,在UI层中使用它们是否可以接受? 也就是说,生成的类之一是BookInfo ,其中包含有关公共图书馆的书籍(标题,版本,页面,摘要等)。

我的BLL将包含一个类BooksBLL ,例如:

public class BooksBLL
{
    ObjectContext _context;

    public void AddBook(BookInfo book) { ... }
    public void DeleteBook(int bookID) { ... }
    public void UpdateBook(int bookID, BookInfo newBook) { ... }

    //Advanced search taking possibly all fields into consideration
    public List<BookInfo> ResolveSearch(Func<BookInfo, bool> filter) { ... }

    //etc...
}

因此,我的MVVM UI应用程序中的ViewModel将与上述BLL类进行通信并交换BookInfo实例。 这样可以吗?

此外,Web上的MVVM帖子建议实现IDataErrorInfo以进行验证。 如果我在生成的POCO类上实现所述接口可以吗? 我从样本中看到那些生成的POCO类包含所有虚拟属性和stuf,我希望添加自己的逻辑可以吗?

如果它有任何区别,目前,我的应用程序不使用WCF(或任何网络的东西)。

此外,如果您发现我正在尝试构建BLL的方式出现严重错误,请随时在该区域提供帮助。

更新(根据要求提供附加信息):

我正在尝试创建一个库自动化应用程序。 目前它不是基于网络的。

我正在考虑如下图层:

  • 由生成的POCO类(BookInfo,作者,成员,发布者,联系人等)组成的项目
  • 具有ObjectContext派生类(DAL?)的项目
  • 一个业务逻辑层,其类似于我上面提到的类(BooksBLL,AuthorsBLL等)
  • 使用MVVM模式的WPF UI层。 (因此我关于IDataErrorInfo实现的子问题)。

所以我想知道在ViewModel类中使用BooksBLL的实例,在其上调用ResolveSearch()以获取List<BookInfo>并呈现它......也就是说,在任何地方使用POCO类。

或者我是否应该有其他类来反映从我的BLL中暴露的POCO类?

如果需要更多细节,请询问。

您正在做的基本上是Repository模式,Entity Framework和POCO非常适合。

因此,我的MVVM UI应用程序中的ViewModel将与上述BLL类进行通信并交换BookInfo实例。 这样可以吗?

这正是POCO对象的用途; 生成的类与如何手动编写它们之间没有区别。 它是您的ObjectContext,它封装了将所有更改保存回数据库的所有逻辑,并且不会直接暴露给您的UI。

我个人并不熟悉IDataErrorInfo但如果现在你的实体只会在这个应用程序中使用,我认为没有任何理由不将它直接放在生成的类中。 如果可能的话,将它添加到T4模板将是理想的,如果错误消息遵循任何逻辑模式,它将节省您必须为每个类手动编码。

此外,如果您发现我正在尝试构建BLL的方式出现严重错误,请随时在该区域提供帮助。

这绝不是错误的,但是如果你计划针对BLL编写单元测试(我建议),你需要将ObjectContext成员更改为IObjectContext 这样,您可以在运行时替换任何实现IObjectContext接口的类(例如您的实际 ObjectContext ),这将允许您针对内存(即模拟)上下文进行测试,而不必访问数据库。

同样,考虑用某种接口替换List<BookInfo> ,例如IList<BookInfo>IBindingList<BookInfo>或最小公分母IEnumerable<BookInfo> 这样你就不会直接绑定到特定的类List<T> ,如果你的需求随着时间而变化,这往往会发生,它将减少用其他东西替换List<BookInfo>所需的重构,假设你有什么重新替换它实现您选择的接口。

不需要做什么特别的事......马克说,没有“正确”的答案。 但是,如果您的应用程序非常简单,您只需复制您的类(例如BookInfoUI和BookInfoBLL),那么我建议您只使用业务类。 额外的层不会起作用,因此它不应该存在。 DDD中的Eric Evans甚至建议将所有逻辑放在UI层中,如果你的应用很简单并且业务逻辑很少。

为了区分,应用程序层应该具有对应用程序内发生的事情进行建模的类,并且域层应该具有模拟域中发生的事件的类。 例如,如果您有一个搜索页面,您的UI层可能会从应用程序层中的BookSearchService检索BookSearchResult对象列表,该列表将使用该域来提取BookInfo列表。

您的问题的答案可能取决于您的应用程序的大小和复杂性。 因此,我担心会有正确的论据来回答您的问题,也可以使用是和否。

就个人而言,我将用是的回答你的两个主要问题:

在UI层中使用POCO(域)类是否可以接受?

我想用“UI层”你实际上并不是指MVVM模式的View部分而是ViewModels。 (我相信大多数MVVM专家会反对让View直接引用模型。)

将POCO从您的Domain项目作为属性包装到ViewModel并将此包装的POCO直接绑定到View并不罕见。 最大的专业是:这很简单。 您不需要ViewModel中的其他ViewModel类或复制属性,然后在对象之间复制这些属性。

但是,如果您使用WPF,则必须考虑绑定引擎如果将它们绑定到View,将直接写入POCO属性。 这可能并不总是您想要的,特别是如果您正在使用WPF表单中的附加和更改跟踪实体。 您必须考虑取消方案或如何在取消后恢复属性,这些属性已由绑定引擎更改。

在我当前的项目中,我正在处理分离的实体:我从数据层加载POCO,从上下文中分离它,处理上下文,然后在ViewModel中使用该副本并将其绑定到View。 通过创建新上下文,通过ID从DB加载原始实体,然后从绑定到View的已更改POCO更新属性,可以在数据层中进行更新。 因此,附加实体的不受欢迎的变化问题随着这种方法而消失。 但是使用分离的entites也有缺点(例如更新更复杂)。

如果我在生成的POCO类上实现IDataErrorInfo接口可以吗?

如果将POCO实体绑定到View(通过包装ViewModel),它不仅可以,而且如果要利用WPF绑定引擎的内置属性验证,甚至必须在POCO类上实现IDataErrorInfo 虽然此接口主要与UI技术一起使用,但它是System.ComponentModel命名空间的一部分,因此不直接绑定到任何UI命名空间。 基本上IDataErrorInfo只是一个简单的契约,它支持报告对象的状态,这也可能在UI上下文之外有用。

对于INotifyPropertyChanged接口也是如此,如果将它们直接绑定到View,您还需要在POCO类上实现它。

出于几个架构原因,我经常会看到不同意我的意见。 但这些观点都没有说明另一种方法更容易。 如果您严格要避免在ViewModel层中使用POCO模型类,则需要添加另一个具有额外复杂性以及编程和维护工作的映射层。 所以我会投票:保持简单,只要你没有令人信服的理由和明确的好处,使你的架构更复杂。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM