Ken*_*ran 4 c# abstraction domain-driven-design repository
我正在使用DDD技术编写应用程序.这是我第一次尝试DDD项目.这也是我的第一个绿地项目,我是唯一的开发商.我充实了域模型和用户界面.现在我开始使用持久层.像往常一样,我开始进行单元测试.
[Test]
public void ShouldAddEmployerToCollection()
{
var employerRepository = new EmployerRepository();
var employer = _mockery.NewMock<Employer>();
employerRepository.Add(employer);
_mockery.VerifyAllExpectationsHaveBeenMet();
}
Run Code Online (Sandbox Code Playgroud)
如您所见,我没有对Add()函数写任何期望.我做到了这一点,并意识到我还没有确定一个特定的数据库供应商.事实上,我甚至不确定它是否需要数据库引擎.平面文件或xml可能同样合理.所以我想知道我的下一步应该是什么.
我应该添加另一层抽象...说一个DataStore接口还是找一个已经为我完成工作的现有库?如果可以的话,我想避免将程序绑定到特定的数据库技术.
根据您的要求,您真正需要的唯一抽象是具有基本CRUD语义的存储库接口,以便您的客户端代码和协作对象仅处理IEmployerRepository对象而不是具体的存储库.你有几个选择:
1)没有更多的抽象.只需在您需要的顶级应用程序中构建具体的存储库:
IEmployeeRepository repository = new StubEmployeeRepository();
IEmployee employee = repository.GetEmployee(id);
Run Code Online (Sandbox Code Playgroud)
在百万个地方改变它将变老,所以这种技术对于非常小的项目才真正可行.
2)创建要在应用程序中使用的存储库工厂:
IEmployeeRepository repository = repositoryFactory<IEmployee>.CreateRepository();
IEmployee employee = repository.GetEmployee(id);
Run Code Online (Sandbox Code Playgroud)
您可以将存储库工厂传递给将使用它的类,或者您可以创建一个应用程序级静态变量来保存它(它是一个单例,这是不幸的,但是相当有限).
3)使用依赖注入容器(基本上是通用工厂和配置机制):
// A lot of DI containers use this 'Resolve' format.
IEmployeeRepository repository = container.Resolve<IEmployee>();
IEmployee employee = repository.GetEmployee(id);
Run Code Online (Sandbox Code Playgroud)
如果你以前没有使用DI容器,有很多很好的问题和解答关于他们在这里SO(如哪些C#/.NET的依赖注入框架是值得研究的?和数据访问,单元测试,依赖注入),你一定要阅读Martin Fowler的Inversion of Control Containers和依赖注入模式.