gpt4 book ai didi

c# - 使用也需要实例化的私有(private)对象实例化类的最佳方法

转载 作者:太空宇宙 更新时间:2023-11-03 18:20:44 25 4
gpt4 key购买 nike

我有一个要实例化的类 MyClass,它包含一个私有(private)属性 ObjectRepository,我想在 MyClass 的构造函数时实例化它> 被调用。

public MyClass
{
private ObjectRepository _objectRepository;

public MyClass()
{

}
}

MyClass 被实例化以添加到列表中:

objects.Add(new MyClass());

遵循 SOLID 原则最干净的方法是什么?

----编辑----

我还忘记提及的是,当我为 MyClass 编写单元测试时,我希望能够模拟 ObjectRepository。当 ObjectRepositoryMyClass 的构造函数实例化时,这是不可能的,因为在测试中没有对 _objectRepository 的引用可用。

最佳答案

为此,您需要查看 SOLID 中的 D:依赖倒置

MyClass 需要一个 ObjectRepository 的实例来完成它所做的一切;它对 ObjectRepository 具有依赖性。根据依赖倒置原则,它应该依赖于抽象,而不是具体类型。在 C# 中,执行此操作的通常方法是使用接口(interface),例如 IObjectRepository,其中包含 MyClass 需要的所有方法,但除此之外别无其他。也可以使用抽象基类来完成,但这不太常见。

当然,如果你依赖于一个接口(interface),你不知道实现它的具体类型,所以你不能实例化它。这可以;您只需要提供一个实例即可。

public MyClass
{
private IObjectRepository _objectRepository;

public MyClass(IObjectRepository objectRepository)
{
_objectRepository = objectRepository;
}
}

现在,当您创建 MyClass 的实例时,您必须为其提供实现 IObjectRepository 的东西。

objects.Add(new MyClass(new ObjectRepository()));

在很多情况下,这就足够了。但是,对于大型对象图,像这样手动创建所有内容可能既费力又重复。解决这个问题的通常方法是使用像 IoC 容器这样的依赖注入(inject)服务。 IoC 代表控制反转,因为你正在反转事物的创造。 IoC 容器不是实例化顶部的东西并让每个东西创建它需要的东西,而是从底部开始,创建需要的东西,然后使用它来创建依赖它的东西,等等。您可以如何使用它的示例如下:

var container = new SomeIoCContainer();
container.For<IObjectRepository>().Use<ObjectRepository>();

var myClass = container.Resolve<MyClass>();

(示例语法;这在不同的 IoC 容器之间有所不同,但它们通常是这样的。)

在许多情况下,您会发现 IoC 容器可以集成到您的应用程序中,这意味着您甚至不需要显式调用容器来解决问题。例如,ASP.NET 就是为此而构建的,因此一旦配置了容器,您只需将构造函数参数添加到 Controller ,框架就会使用容器为您提供这些参数。

这种方法的优点:

  • 如果你想测试 MyClass 中发生的事情,你可以简单地给它一个假的 IObjectRepository 版本,它不会做任何复杂的事情,这样你可以用更少的工作设置您的测试,并且您知道您在 MyClass 上的测试不会受到 ObjectRepository 中可能发生的不相关事情的影响。您可以通过为测试设置一个单独的容器来完成此操作,但通常手动执行此操作更容易 - 您只测试一件事,而您的模拟依赖项不应该依赖于任何东西。
  • 随着您的应用程序的增长和变得越来越复杂,您不必担心如何创建事物所依赖的所有组件 - 您只需告诉您的 IoC 容器它们是什么,它就会负责创建事物。
  • 如果您需要更改其中一个依赖项的工作方式,那就容易多了。例如,如果您有一个从 SQL 数据库获取对象的 DatabaseObjectRepository,并且您想要将其替换为一个从 Web 服务获取对象的 WebClientObjectRepository,您只需实现相同的接口(interface)并更改您告诉容器将什么用于 IObjectRepository 的那一行,它就会为您交换应用程序中的所有用法。

关于c# - 使用也需要实例化的私有(private)对象实例化类的最佳方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56126111/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com