【发布时间】:2016-08-23 19:08:30
【问题描述】:
在我的 WPF 应用程序中,我创建了两个独立的项目:UI(带有 XAML 和 ViewModel)和“核心”(它具有人们所谓的“域对象”或“业务对象”——代表离散概念的对象在我的用例中)。我知道这是一个很好的做法。
但我的许多业务对象都与多个数据源交互。例如,Document 对象可能包含来自数据库和文件的数据。
然后,你可以用Document“做”一些事情——我在Document上作为方法实现——涉及其他资源。例如,Document.SubmitForProcessing() 调用 Web 服务。
所以我写了这个:
public class Document
{
public string Name { get; set; }
public string FilePath { get; set; }
public string FileData { get; set; }
private Document() { }
public static Document GetByID(int documentID, string databaseConnectionString, string baseFilePath)
{
// Using Dapper
Document newDoc = db.Query<Document>("SELECT Name, FilePath FROM Documents WHERE ID = @pID", new { pID = documentID });
newDoc.FileData = File.ReadAllText(Path.Combine(basePath, newDoc.FilePath));
return newDoc;
}
public void SubmitForProcessing(IWebService webService)
{
webService.ExecuteFoo(this.Name, this.FileData);
}
public void DoBusinessStuff()
{
this.FileData = this.FileData.Replace("foo", "bar");
}
}
不用说,这很快就变得超级烦人,并且很难针对它编写测试。
所以我读到了依赖注入和存储库模式。但我不确定如何在这种情况下正确地做到这一点。我是否对每个数据源都有单独的存储库类,然后是某种 DocumentFactory 或访问单独存储库并将 Document 对象拼接在一起的东西?还是有更简单的方法?
我主要关心的是使代码易于测试,这样我就可以编写一些单元测试而无需模拟整个数据库和文件系统,而且还可以停止将一大堆参数传递给我拥有的每个工厂方法(例如GetByID(int documentID, string databaseConnectionString, string baseFilePath) - 我的现实生活中有超过六个这样的参数)。
在类似的问题上,答案涉及 SOLID、YAGNI、用于 CRUD 的存储库等。我重视这些原则,但我无法从中获得实用的设计。例如,Web 服务并不是真正的 CRUD-y。我是否有一个“存储库”,以便我可以在单元测试期间将其切换出来?文件系统呢?
TL;DR - 该代码有什么问题?
感谢您的指导。谢谢!
【问题讨论】:
标签: c# wpf oop design-patterns