Bun*_*nut 1 c# solid-principles
我有一个MyClass要实例化的类,该类包含一个私有属性ObjectRepository,该私有属性在MyClass调用的构造函数时要实例化。
public MyClass
{
private ObjectRepository _objectRepository;
public MyClass()
{
}
}
Run Code Online (Sandbox Code Playgroud)
MyClass 实例化以添加到列表中:
objects.Add(new MyClass());
Run Code Online (Sandbox Code Playgroud)
遵循SOLID原则,最干净的方法是什么?
- - 编辑 - -
我还忘了提到的是,当我编写单元测试时,MyClass我希望能够进行模拟ObjectRepository。ObjectRepository从的构造函数实例化时,这是不可能的MyClass,因为测试中没有对的引用_objectRepository。
为此,您需要查看SOLID中的D:依赖关系倒置。
MyClass需要一个实例ObjectRepository来做任何事情;它有一个依赖上ObjectRepository。根据依赖倒置原则,它应改为依赖抽象而不是具体类型。在C#中,执行此操作的通常方法是使用接口(如)IObjectRepository,该接口上具有所需的所有方法MyClass,但仅此而已。也可以使用抽象基类来完成,但这并不常见。
当然,如果您依赖于接口,那么您将不知道实现该接口的具体类型,因此无法实例化它。这可以; 您只需要提供一个实例即可。
public MyClass
{
private IObjectRepository _objectRepository;
public MyClass(IObjectRepository objectRepository)
{
_objectRepository = objectRepository;
}
}
Run Code Online (Sandbox Code Playgroud)
现在,当您创建的实例时MyClass,必须为其提供实现的东西IObjectRepository。
objects.Add(new MyClass(new ObjectRepository()));
Run Code Online (Sandbox Code Playgroud)
在许多情况下,这就足够了。但是,对于大型对象图,像这样手动创建所有内容可能既费力又重复。解决此问题的通常方法是使用类似IoC容器的依赖项注入服务。IoC代表控制权的反转,因为您正在颠倒事物的创造。IoC容器不是实例化顶部的内容并让每个事物创建它所需的事物,而是从底部开始,创建所需的事物,然后使用该容器创建依赖于它的事物,依此类推。有关如何使用它的示例如下:
var container = new SomeIoCContainer();
container.For<IObjectRepository>().Use<ObjectRepository>();
var myClass = container.Resolve<MyClass>();
Run Code Online (Sandbox Code Playgroud)
(示例语法;这从一个IoC容器到另一个IoC容器有所不同,但是它们通常是这样的。)
在许多情况下,您会发现IoC容器可以集成到您的应用程序中,这意味着您甚至不需要显式调用容器来解决问题。例如,ASP.NET是为此目的而构建的,因此,一旦配置了容器,就可以将构造函数参数添加到控制器中,框架将使用该容器为您提供这些参数。
这种方法的优点:
MyClass,你可以简单地给它的仿版IObjectRepository是不会做任何事情复杂,让你可以设置你的测试少得多的工作,你知道你在考试MyClass韩元”不受内部可能发生的不相关事物的影响ObjectRepository。您可以通过为测试设置一个单独的容器来执行此操作,但是通常手动操作更容易-您仅测试一件事,并且您的模拟依赖项不依赖任何内容。DatabaseObjectRepository从SQL数据库获取对象的,而又想将其交换为WebClientObjectRepository从Web服务获取对象的a,则只需实现相同的接口,然后更改告诉容器的那一行用作IObjectRepository,它将为您交换应用程序中的所有用法。| 归档时间: |
|
| 查看次数: |
89 次 |
| 最近记录: |