我的程序现在有4层……
Web (Project | ASP.NET MVC Application) – References Models.dll and Persistence.dll
Models (Domain Objects)
Persistence (Fluent nHibernate Mapping of Domain Objects)
Utilities (Providers,Repositories)
现在,我正在尝试编写一个简单的Membership Repository.我的第一个任务……?
当有人试图注册时,检查是否存在电子邮件地址.这似乎一切都很好 – 所以我去尝试找出放置它的位置.
首先,我只是将它放在MembershipProvider类的CreateUser方法中.然而,这属于公用事业项目.到目前为止,Utilities还不了解nHibernate.只有Persistence Project对nHibernate有任何了解.
那么,我的CreateUser方法需要查询我的数据库.那么这里最好的做法是什么?我是否在Persistence项目中创建UserRepository,并创建一个名为CheckEmail的整个方法?或者我只是将nHibernate .dll添加到我的Utilities项目中,并在Provider中编写会话查找?
在我的持久性项目中制作存储库以执行特定操作而不是创建提供程序似乎更多的工作.如果我必须为他们制作存储库,为什么我甚至会创建提供商?所有这些新方法的目的不是停止代码重复吗?但感觉就像保持“分开”我必须写相同的代码2或3次.这里的最佳做法是什么?
解决方法
您的CreateUser方法不应直接查询数据库以确定电子邮件地址是否已存在,而是在您的DoesEmailExist中创建一个单独的方法,该方法负责执行该检查.每种方法都应该有一个责任.
回应jfar的疑虑:
没错,域定义了可以做什么,定义了Domain.IUserRepository.Create(用户用户)等接口.但是,域不定义任何实现.
假设您开始使用Entity Framework,您可以创建一个Persistence程序集,它实现域中定义的接口.所以继上面的域界面后我们实现了接口:
namespace Persistence { public class UserRepository : Domain.IUserRepository { public void Create(User user) { // use Entity Framework to persist a user } } }
比方说,您的客户稍后会告诉您实现NHibernate持久层.幸运的是,我们的域与现有的持久层是分开的 – 它位于域中.因此,您可以轻松实现现有的域接口,而无需更改MVC应用程序中的任何代码 – 因为所有知道的是您定义的接口,而不是实体框架实现.
然后可以将您的IoC容器配置为将IUserRepository解析为Entity Framework或NHibernate实现,您的MVC应用程序无关紧要.
就汇编引用而言,Persistence程序集具有对Domain的引用,而Domain恰当地没有对Persistence的引用.
这导致了解耦设计,易于测试,并且向前更改,从而使维护更容易.
我希望有所帮助.