Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/284.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 注入作为依赖项树的依赖项_C#_Design Patterns_Dependency Injection_Anti Patterns - Fatal编程技术网

C# 注入作为依赖项树的依赖项

C# 注入作为依赖项树的依赖项,c#,design-patterns,dependency-injection,anti-patterns,C#,Design Patterns,Dependency Injection,Anti Patterns,注入依赖项是依赖项树,这是一种模式还是反模式 例如: public class ClassExample { private IContainer _container; public ClassExample(IContainer container) { _container = container; } } public interface IContainer { IDependencyA DependencyA { get;

注入依赖项是依赖项树,这是一种模式还是反模式

例如:

public class ClassExample
{
    private IContainer _container;

    public ClassExample(IContainer container)
    {
        _container = container;
    }
}

public interface IContainer
{
    IDependencyA DependencyA { get; set; }
    IDependencyB DependencyB { get; set; }
    IDependencyC DependencyC { get; set; }
}

public interface IDependencyA
{
}

public interface IDependencyB
{
}

public interface IDependencyC
{
}
上面的例子可以做得更深入(一棵树)——例如IDependencyA可以包含更多的依赖项IDependencyAA、IDependencyAB等等

当需要注入同一组服务的多个位置时,有人可能会使用上述方法来最小化代码重复。在许多情况下,代码最终会看起来像:container.DependencyA.DependencyAA.Method(…),这会使它更冗长、更枯燥


使用上述方法是好主意还是坏主意(模式/反模式)?或者什么时候这是个好主意,什么时候是个坏主意?

我认为这不是一个特别好的模式*,但同样的道理,这不会产生很大的影响

如果使用您的示例,
ClassExample
依赖于
IDependencyA
IDependencyB
&
IDependencyC
,那么它们都应该作为依赖项注入

更常见的是,
IDependencyXX
类的具体实现本身具有依赖性,但不会像您描述的那样将它们公开给
ClassExample



*这是一个错误的决定,主要是因为人们迟早会在只需要
IDependencyA
IDependencyB
(而不是
IDependencyC
)的时候开始注射
IContainer
。这是多余的。注入的全部要点是注入您需要的依赖项,而不是来自系统的所有可能的依赖项“以防万一”

我不认为这是一种特别好的模式*,但同样地,它不会产生巨大的差异

如果使用您的示例,
ClassExample
依赖于
IDependencyA
IDependencyB
&
IDependencyC
,那么它们都应该作为依赖项注入

更常见的是,
IDependencyXX
类的具体实现本身具有依赖性,但不会像您描述的那样将它们公开给
ClassExample



*这是一个错误的决定,主要是因为人们迟早会在只需要
IDependencyA
IDependencyB
(而不是
IDependencyC
)的时候开始注射
IContainer
。这是多余的。注入的整个要点是注入所需的依赖项,而不是来自系统的所有可能的依赖项“以防万一”

“需要注入同一组服务的多个位置”——听起来您可以使用抽象基类。“代码最终看起来像:container.DependencyA.DependencyAA.Method(…)”-看起来您没有很好地隐藏实现。如果希望
DependencyA
执行某项操作,为什么需要知道它又有一个
DependencyAA
,其中包含要调用的实际
方法()?如果你想隐藏一个类的依赖关系的数量,那么依赖性注入是很好的。依赖关系的数量是合理的,但是它往往会导致依赖于注入的依赖性,这是一种反模式。为了解决这个问题,我们可以使用工厂,但在此之前,我们应该考虑到,我们可能已经打破了单一责任原则,这一类可以分裂成几类。使用工厂来减少依赖的数量往往无济于事。您要么注入工厂(在这种情况下注入的依赖项的数量保持不变),要么有效地使用服务定位器——它不会减少依赖项的数量,只是隐藏了它们。您的
IContainer
抽象的主要问题是它没有隐藏
ClassExample
的复杂性。尽管它可能会消除构造函数过度注入代码的味道,但它并不能解决为什么构造函数过度注入首先会发生的根本问题。最有可能的是,依赖项太多的类太复杂;它违反了单一责任原则。用
IContainer
抽象包装依赖项并不会改变这一点。“有多个地方需要注入一组相同的服务”——听起来您可以使用抽象基类。“代码最终看起来像:container.DependencyA.DependencyAA.Method(…)”-看起来您没有很好地隐藏实现。如果希望
DependencyA
执行某项操作,为什么需要知道它又有一个
DependencyAA
,其中包含要调用的实际
方法()?如果你想隐藏一个类的依赖关系的数量,那么依赖性注入是很好的。依赖关系的数量是合理的,但是它往往会导致依赖于注入的依赖性,这是一种反模式。为了解决这个问题,我们可以使用工厂,但在此之前,我们应该考虑到,我们可能已经打破了单一责任原则,这一类可以分裂成几类。使用工厂来减少依赖的数量往往无济于事。您要么注入工厂(在这种情况下注入的依赖项的数量保持不变),要么有效地使用服务定位器——它不会减少依赖项的数量,只是隐藏了它们。您的
IContainer
抽象的主要问题是它没有隐藏
ClassExample
的复杂性。尽管它可能会消除构造函数过度注入代码的味道,但它并不能解决为什么构造函数过度注入会在第一个pl中发生的根本问题