Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/325.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#_Dependency Injection_Simple Injector - Fatal编程技术网

C# 目录概念而不是复杂的构造函数?

C# 目录概念而不是复杂的构造函数?,c#,dependency-injection,simple-injector,C#,Dependency Injection,Simple Injector,在我当前的项目中,我的经理正在强迫我讨论依赖注入的一些设计概念,因为我很好奇依赖注入专家对这种方法的看法。这背后的思想是使用一个名为catalog的类,该类是针对每个服务(服务结构中的服务)实现的,并且内部具有如下所有依赖项: public interface IDepA { } public interface IDepB { } public interface IDepC { } public class StandardConstructorInjectorService {

在我当前的项目中,我的经理正在强迫我讨论依赖注入的一些设计概念,因为我很好奇依赖注入专家对这种方法的看法。这背后的思想是使用一个名为catalog的类,该类是针对每个服务(服务结构中的服务)实现的,并且内部具有如下所有依赖项:

public interface IDepA
{
}

public interface IDepB
{
}

public interface IDepC
{
}

public class StandardConstructorInjectorService
{
    private readonly IDepA _depA;
    private readonly IDepB _depB;
    private readonly IDepC _depC;

    public StandardConstructorInjectorService(IDepA depA, IDepB depB, IDepC depC)
    {
        _depA = depA;
        _depB = depB;
        _depC = depC;
    }
}

public class ServiceCatalog
{
    private readonly Container _container;

    public ServiceCatalog(Container container)
    {
        _container = container;
    }

    public IDepA DepA => _container.GetInstance<IDepA>();
    public IDepB DepB => _container.GetInstance<IDepB>();
    public IDepC DepC => _container.GetInstance<IDepC>();
}

public class ServiceWithCatalog
{
    private readonly ServiceCatalog _catalog;

    public ServiceWithCatalog(ServiceCatalog catalog)
    {
        _catalog = catalog;
    }
}
公共接口IDepA
{
}
公共接口IDepB
{
}
公共接口IDepC
{
}
公共类标准ConstructorInjectorService
{
私有只读IDepA_depA;
私有只读IDepB_depB;
私有只读IDepC_depC;
公共标准施工人员服务(IDepA depA、IDepB depB、IDepC depC)
{
_depA=depA;
_depB=depB;
_depC=depC;
}
}
公共类服务目录
{
私有只读容器_容器;
公共服务目录(容器)
{
_容器=容器;
}
public IDepA DepA=>_container.GetInstance();
public IDepB DepB=>_container.GetInstance();
public IDepC DepC=>_container.GetInstance();
}
公共类ServiceWithCatalog
{
专用只读ServiceCatalog\u目录;
公共服务WithCatalog(服务目录目录)
{
_目录=目录;
}
}
在我看来,我们有

优点:

  • 使用目录的代码很简单
  • 依赖项可以在惰性模式下使用,所以当代码逻辑不使用它们时,它们不会被创建——但另一方面,我知道我们应该以这样的方式设计类,它们将使用所有依赖项
  • 这些类很容易引导,因为它们有一个预定义的目录
  • 缺点:

  • 类的依赖项不直接可见
  • 嗅到服务定位器的气味,但我们只在目录定义中使用解析,而不在业务代码中使用解析,所以我不确定这是否可以接受,或者依赖注入警察可能会追捕我们:)

  • 你认为这种方法怎么样

    您的
    服务目录
    类取决于
    容器
    。这有效地使其成为一个服务定位器,它是一个。此类不是“业务代码”这一事实与此无关。唯一重要的是,它不是的一部分,这使得它成为一个反模式

    除了使用反模式外,该类还公开其依赖项,而不是隐藏它们,这也是一个坏主意。该类的主要思想可能是将常用的依赖项组合在一起,从而减少类具有的构造函数依赖项的数量。然而,这样做的问题是,它并没有降低消费类的复杂性,只是掩盖了一个类有太多依赖项的事实。依赖项过多的类可能违反了单一责任原则

    不要使用此服务目录“模式”,而是坚持使用构造函数注入。当一个类获得太多的构造函数依赖项时,应该采取一种称为构造函数过度注入的代码气味。有很多解决方案,例如,装饰器或域事件。门面服务隐藏其依赖项,而不是公开它们


    Mark Seemann和我可以阅读所有这些信息以及更多信息。

    亲爱的收信人,这个问题主要不是基于意见的。@Steven这是你的意见。@itsme86:不太可能。所示的代码演示了一些众所周知的、有良好文档记录的反模式。正因为如此,这个问题可以用一种合理的非意见化的方式来回答。@Steven你认为所显示的代码是反模式是你的观点。您(或其他人)已经记录了该意见,这并不会使其成为一种意见。好吧,这不是一个纯粹的服务定位器,而是非常接近和。。。更糟。它就像一个神工厂。。“目录”几乎强制所有使用点了解所有同级的所有依赖关系。之所以保存,是因为C#编译器在剥离它们时有点困难,但是目录仍然依赖于所有这些元素,这对于normalna ioc容器来说是不正确的