【发布时间】:2017-01-15 16:56:59
【问题描述】:
我想将依赖注入和控制反转应用到我的日常开发中。假设我有一个SomeObject 的对象类型(实现接口ISomeObject)。我有一个使用这个对象的类,称为 Data ,它实现了IData 接口。
public interface ISomeObject {
int ID;
string Name;
bool IsAwesome;
void DoSomeStuffIfAwesome();
}
public Class SomeObject : ISomeObject {
int ID;
string Name;
bool IsAwesome;
void DoSomeStuffIfAwesome() { /*stuff happens here*/ }
}
public interface IData {
List<ISomeObject> GetSomeObjects();
}
public Class Data : IData {
List<ISomeObject> GetSomeObjects()
{
List<ISomeObject> objects = new List<ISomeObject>; // ??? Maybe and cast later?
//do some SQL stuff and get a SqlDataReader object called reader
while(reader.Read()) {
//ISomeObject someObj = ???
//Read into the someObj.ID, someObj.Name and someObj.IsAwesome fields
objects.add(someObj);
}
return objects;
}
}
GetSomeObjects() 方法生成ISomeObject 对象的列表。但我不希望Data.cs 将与SomeObject 相关的任何内容硬编码到其中。我想要某种形式的依赖注入来解决运行时的问题。处理这个问题的最佳方法是什么?我考虑了以下几点:
1.将SomeObject 的实例传递给Data 的构造函数。 这样我可以使用.GetType() 获取它的类型,将其存储到Data.cs 中的私有System.Type 变量中,然后在中使用Activator.CreateInstance循环创建要添加到列表中的新对象。 Data 需要了解 SomeObject 类,如果我理解正确的话。
2。将我的 IoC 容器实例传递给 Data 的构造函数,然后使用 container.Resolve<ISomeObject>() 解析对象类型。如果不使用我的 IoC 容器,这将使GetSomeObjects() 方法的单元测试变得困难。我读过我不应该在单元测试期间使用 IoC 容器,而应该手动将我需要的东西传递给方法。
3.传递一个已实例化为 SomeObject 的 ISomeObject 对象 - 然后我将使用它通过一些内置方法创建对象,例如 SomeObject.GenerateList(IDataReader reader)。
【问题讨论】:
-
在某些时候,一个类必须是具体的。为什么
IData的那个 实现不知道如何返回一组特定的ISomeObject对象? -
很可能就是这种情况。我的理解是 IoC 和依赖注入的目标是让消费者只知道接口,而不是具体类,这样我就可以快速更换具体类,而无需修改消费者。因此,如果将来我想用另一个实现 ISomeObject 的类来替换 SomeObject,我可以在不接触 Data.cs 的情况下这样做。很可能是我对抽象的想法太深入了,需要稍微调整一下。也许我确实需要在 Data.cs 中实例化 SomeObject
-
使用工厂 (
ISomeObjectFactory) 获取阅读器并返回ISomeObject。将工厂注入Data,工厂将知道如何构造ISomeObject。
标签: c# unit-testing dependency-injection inversion-of-control abstraction