【发布时间】:2013-11-27 16:57:35
【问题描述】:
我目前正在将大型 Web 服务转换为使用存储库模式和依赖注入。我们正在扩大我们的团队,可靠的单元测试带来的好处超过了重构代码所需的努力。
根据同事的推荐,我选择了 Ninject 作为我的框架,并开始重构我的代码。这涉及创建一个包含对象本身的“Common”项目、一个包含数据访问逻辑的 Repository.Database 项目,以及一个使用这两者的 Web 服务。我使用了基于约定的映射,因此 IPersonRepository 应该映射到我的具体 PersonRepository 类。
我目前正在使用 [Inject] 属性在每个类上创建一个“存储库”属性的方法,然后替换我的构造函数以使用所述存储库,但遇到了我的第一个绊脚石并且我不相信我在做事情正确的方式。在我开始这一切之前,我会像这样实例化一个对象:
var p = new Person(ID);
使用我建议的格式,我的班级看起来像这样:
[Inject]
public IPersonRepository Repository { get; set; }
public string Name;
public Person(int ID)
{
// This feels wrong
var p = Repository.Get(ID);
Name = p.Name;
}
您可能会看到我的难题。如何使用构造函数而不必从存储库返回新对象,然后将每个字段映射到当前对象?我不能替换“this”,虽然我可以使用 AutoMapper 之类的东西一次性映射每个字段,但感觉就像我在这里做的事情本身就是错误的。
我可以使用静态方法代替注入器:
[Inject]
public static IPersonRepository Repository { get; set; }
public string Name;
public static Person GetByID(int ID)
{
return Repository.Get(ID);
}
但是正如您所看到的,它需要将 Repository 设为静态,并且感觉我应该使用构造函数而不是静态的“GetByID”方法。那可能只是因为我太习惯使用构造函数了。
或者,我可以将 Repository 传递给 Person 构造函数,但是每次我在代码中实例化 Person 时,都会感觉很麻烦。
我想要实现的是让我现有的 WCF 项目使用一个存储库加载其所有数据,并让我的单元测试项目使用另一个存储库加载其所有数据。我不想在其中传递 IPersonRepository 的具体实现。这是可以实现的,甚至是推荐的吗?
【问题讨论】:
-
您的域模型对象不应依赖于您的存储库
-
该类依赖于 IPersonRepository 但不依赖于它的实现。这不是可以接受的吗?
-
不,这不好。
Person不应该知道IPersonRepository
标签: c# dependency-injection ninject repository-pattern