我遇到了一个问题。我创建了一个使用IoC的解决方案。但是,我有一个致命的缺陷 - 我使用的主要DTO(数据传输对象 - 所以,通过图层的类)包含,例如,具有名称,姓氏,DateOfBirth,StatusId ...和列表的人有效状态。
创建Person类时会填充状态,并且数据来自参考数据存储库...此存储库是一个单例并从缓存中获取数据(最初是从数据库获取数据)。
所以,
Name string {get; set;}
Surname string {get; set;}
StatusId int {get; set;}
Statuses List<ReferenceItem> {get; set;} = ReferenceData.GetData(DataType.ClientStatus);
在我的单元测试中,我最终依赖于ReferenceData类,它是一个单例。有没有办法以某种方式注入模拟ReferenceData类?或者我的设计存在缺陷,我需要重新设计我的Person类吗?
答案 0 :(得分:2)
你必须重新设计你的类并使用构造函数注入。 按照这个例子(指你的):
class Person {
public string Name { get; set; }
public string Surname { get; set; }
public int StatusId { get; set; }
public List<ReferenceItem> Statuses { get; set; }
public Person(IReferenceDataProvider provider) {
Statuses = provider.GetData(DataType.ClientStatus);
}
}
或者您可以直接使用IoC容器来解析构造函数中的依赖项:
...
public Person() {
var provider = IoC.Resolve<IReferenceDataProvider>();
Statuses = provider.GetData(DataType.ClientStatus);
}
...
无论如何,你必须抽象你的类引用并使用接口。 希望这可以提供帮助。
答案 1 :(得分:1)
正如其他人指出能够测试你的代码一样,你应该重新设计代码是可测试的
我认为,您正在使用DTO(数据传输对象)通过不同的层传递数据,这种责任应该是这些对象应该对其中一个层具有最小的依赖性。
在您的情况下,您的DTO依赖于静态方法或注入接口,甚至更糟糕的是IoC容器。删除所有这些并使您的DTO成为负责数据的对象。
public class Person
{
public string Name{ get; set; }
public string Surname { get; set; }
public int StatusId { get; set; }
public List<ReferenceItem> Statuses { get; set; }
}
然后,在您创建Person实例的任何地方,您都必须注入IReferenceDataProvider
或者,您可以引入Factory抽象来创建Person
public interface IPersonFactory
{
Person Create(string name, string surname, int statusId);
}
实施
public class PersonFactory
{
private readonly IReferenceDataProvider _dataProvider;
public PersonFactory(IReferenceDataProvider dataProvider)
{
_dataProvider = dataProvider;
}
public Person Create(string name, string surname, int statusId)
{
return new Person
{
Name = name,
Surname = surname,
StatusId = statusId,
Statuses = _dataProvider.GetData(DataType.ClientStatus)
};
}
}