Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.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
Asp.net core 继承上的服务定位器模式与服务聚合工厂_Asp.net Core_Dependency Injection - Fatal编程技术网

Asp.net core 继承上的服务定位器模式与服务聚合工厂

Asp.net core 继承上的服务定位器模式与服务聚合工厂,asp.net-core,dependency-injection,Asp.net Core,Dependency Injection,假设我有一个需要大量服务的基类。这个基类有一些派生类 class BaseClass { BaseClass(IServiceA srvA, IServiceB srvB) { ... } } 要使用DI从此基类继承,我需要在派生类中重复构造函数参数: class DerivedClassA { DerivedClassA(IServiceA srvA, IServiceB srvB) : base(srvA, srvB) {} } 当以后基类需要新的依赖项时,我将不得不更改

假设我有一个需要大量服务的基类。这个基类有一些派生类

class BaseClass
{
    BaseClass(IServiceA srvA, IServiceB srvB) { ... }
}
要使用DI从此基类继承,我需要在派生类中重复构造函数参数:

class DerivedClassA
{
    DerivedClassA(IServiceA srvA, IServiceB srvB) : base(srvA, srvB) {}
}
当以后基类需要新的依赖项时,我将不得不更改基类和派生类。想象一下当有几个派生类时的噩梦

class BaseClass
{
    BaseClass(IServiceA srvA, IServiceB srvB) { ... }
}
我做了一些研究,似乎有一个解决方案,即服务聚合工厂(或类似术语):

这样,每次需要向类添加更多服务时,我只需要更改
ServiceFactory
,而不需要更改它们

但是还有
IServiceProvider
,它是.NETCore中的默认DI容器。所以我可以做到:

class BaseClass
{
    public BaseClass(IServiceProvider provider)
    {
        this._srvA = provider.GetRequiredService<IServiceA>();
        this._srvB = provider.GetRequiredService<IServiceB>();
    }
}

class DerivedClassA : BaseClass
{
    public DerivedClassA(IServiceProvider provider) : base(provider) {}
}
类基类
{
公共基类(IServiceProvider提供程序)
{
这是._srvA=provider.GetRequiredService();
这是._srvB=provider.GetRequiredService();
}
}
类派生ClassA:基类
{
public-DerivedClassA(IServiceProvider提供程序):基本(提供程序){}
}
它看起来与服务聚合工厂一样,但人们说直接使用
IServiceProvider
是一种反模式。所以我很困惑。我应该选择哪个选项

假设我有一个需要大量服务的基类。这个基类有一些派生类

class BaseClass
{
    BaseClass(IServiceA srvA, IServiceB srvB) { ... }
}
我不在这里看书了,你也应该这么做。这是一个明确的指标,表明您的基类做得太多了。这违反了公司的SRP(单一责任原则)

构造函数注入使得设计缺陷(如实体违规)非常明显,您应该注意它,因为它告诉您,当您的类有太多的责任时(一个试图做太多的类)

首先也是最重要的,您需要思考为什么基类需要这些依赖项,并对此进行更改。 您的问题是抽象的,所以无法告诉您为什么您的类可能需要这么多依赖项

如果您的类>Eng/St>需要所有这些依赖项,请考虑使用外观。facade是另一个类,它将复杂性和依赖性隐藏在易于使用的接口后面,从而减少依赖性的数量。见马克·希曼的

facade不仅仅是一个类,它提供了对其他依赖项的轻松访问(即一个只有5个表示其他服务的属性的类)。facade将尽可能隐藏依赖项,并提供方法来轻松访问其背后的功能,即
。GetDrives
方法可以枚举硬件设备并扫描其分区,并侦听每个正确格式化的分区,这样调用代码就不必重复

假设您拥有像
IMemoryService
ICpuService
IDiskService
INetworkService
这样的服务,并将它们注入到所有基类中。这有很多依赖关系

相反,您可以有一个
IComputerServices
接口,该接口允许您访问所有这些由易于使用的API/方法/属性隐藏的服务(即
IComputerServices.CopyFileTo
方法,该方法将所有复制操作抽象为一个简单易用的方法,并将其注入到您的服务中。现在,您可以将类似
computerServices.CopyFileTo的文件复制到(sourceFile,destinationFile)

如果出现了新的依赖项,例如
IDisplayService
,您只需将其添加到facade服务中,它将在您的所有类中可用,这些类也会注入
IComputerServices

假设我有一个基类,它需要一组服务,这个基类有一些派生类

class BaseClass
{
    BaseClass(IServiceA srvA, IServiceB srvB) { ... }
}
停止阅读这里的内容,你也应该这样做。这是一个明确的指标,表明你的基类做得太多了。这违反了来自的SRP(单一责任原则)

构造函数注入使得设计缺陷(如实体违规)非常明显,您应该注意它,因为它告诉您,当您的类有太多的责任时(一个试图做太多的类)

首先也是最重要的,您需要思考为什么基类需要这些依赖项,并对此进行更改。 您的问题是抽象的,所以无法告诉您为什么您的类可能需要这么多依赖项

如果您的类<强>真正的< /强>需要所有这些依赖关系,请考虑使用一个Futal.外观是另一个类,它隐藏了一个易于使用的接口背后的复杂性和依赖性,从而减少了依赖性的数量.参见Mark Seemann的.

facade不仅仅是一个类,它提供了对其他依赖项的轻松访问(即,一个只有5个表示其他服务的属性的类).facade将尽可能隐藏依赖项,并提供方法来轻松访问其背后的功能,即
。GetDrives
方法可以枚举硬件设备并扫描其分区,并侦听每个正确格式化的分区,这样调用代码就不必重复

假设您拥有像
IMemoryService
ICpuService
IDiskService
INetworkService
这样的服务,并将它们注入到所有的基类中。这是很多依赖项

相反,您可以有一个
IComputerServices
接口,该接口允许您访问所有这些由易于使用的API/方法/属性隐藏的服务(即
IComputerServices.CopyFileTo
方法,该方法将所有复制操作抽象为一个简单易用的方法,并将其注入到您的服务中。现在,您可以将类似
computerServices.CopyFileTo的文件复制到(sourceFile,destinationFile)

如果出现了新的依赖项,例如
IDisplayService
,您只需将其添加到facade服务中,它将在您的所有类中都可用