ASP.NET Core DI构造函数与RequestServices

马克拉

为什么要通过HttpContext.RequestServicesIServiceProvider考虑不良做法来请求服务我可以到处阅读此声明:

建议使用构造函数注入而不是使用RequestServices进行获取。


我的想法正好相反。尽可能使用RequestServices。让我解释一下原因。我想使控制器尽可能小,以便创建单独的服务。这样,我的控制器就干净了:

public class MyController : Controller
{
    public MyController(IMyServices MyServices){}

    public async Task<IActionResult> GetSomething(int parameter)
    {
       return await this.MyServices.SomeMethod(parameter);
    }
}

所有服务都继承自base,其中包含用于管理权限,缓存sql请求...的逻辑。
通过构造方法,我得到了非常复杂的调用基系统:

public class MyBaseService
{
    public MyBaseService(ILogger Logger, AppDbContext Context, IMemoryCache Cache) { }

    public bool HasRight(string right) { return true; }

    public bool IsLoggedIn() { return true; }
}

public class MyServices : MyBaseService
{
    public MyServices(ILogger Logger, AppDbContext Context, IMemoryCache Cache) : base(Logger, Context, Cache)
    {    
    }
}

但是GetRequiredService我简化了基于构造函数的调用:

public class MyBaseService2
{
    private ServiceProvider _ServiceProvider;
    public MyBaseService2(IServiceProvider ServiceProvider)
    {

    }

    protected ILogger Logger { get { return this._ServiceProvider.GetRequiredService<ILogger>(); } }

    protected AppDbContext Context { get { return this._ServiceProvider.GetRequiredService<AppDbContext>(); } }

    protected IMemoryCache Cache { get { return this._ServiceProvider.GetRequiredService<IMemoryCache>(); } }

    public bool HasRight(string right) { return true; }

    public bool IsLoggedIn() { return true; }
}

public class MyServices2 : MyBaseService2
{
    public MyServices2(IServiceProvider ServiceProvider) : base(ServiceProvider)
    {    
    }
}

是的,BaseService包含更多代码,但是当我在BaseService中需要其他服务时,无需修复每个类的基本构造函数调用。另外,我所有的服务都有更简单的构造函数(只是IServiceProvider)。

如果我反对构造方法。ServiceProvider.GetRequiredService如果存在作用域,则调用MyServices会对性能造成任何影响

史蒂文

为什么通过HttpContext.RequestServices或IServiceProvider请求服务被认为是不好的做法。

这是一种不好的做法,因为它是Service Locator反模式的实现

您试图通过将许多常见的依赖关系和通用的逻辑移到基类中来使控制器类变小,但这本身就是一种反模式,因为:

  • 即使依赖项已从基类中解决,这些依赖项仍被隐藏,如本文所述这意味着从单元测试和DI容器中隐藏了依赖项,而后者将无法对对象图进行分析。
  • 将依赖关系移至基类不会降低类的复杂性,因为基类始终与派生紧密耦合
  • 这导致许多责任被塞到基层,这将导致基层违反“单一责任原则”这可以迫使基层阶级成为上帝的阶级并不断变化。

基类使用继承,而软件开发中的普遍共识是,您应该更喜欢Composition而不是继承

由于您应该支持组合,因此这将自动导致依赖注入。如果没有基类,则立即发现违反“单一责任原则”的问题将变得更加容易,因为您的构造函数将获得更多的参数。再次注意,使用Service Locator时,依赖项的数量不会改变,它们的计数更难。

您应该接受一个事实,即构造器注入很容易导致构造器过度注入,因为这表明我们的课程做得太多,并且表明我们应该重新设计此类。

与其在基类中实现诸如日志记录,缓存和授权之类的横切关注点,不如使用组合实现它们。例如,您可以使用中间件装饰器拦截器将横切关注点应用于请求(或此类请求的特定服务)。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

DI容器如何知道构造函数需要什么(ASP.NET Core)?

不带构造函数参数的.NET Core DI

ASP.Net Core 从构造函数返回结果

.NET Core DI,将参数传递给构造函数的方法

模型中的ASP.NET CORE DI

带ASP.NET Core DI的MediatR

ASP.Net Core DI的策略模式

如果未找到公共默认构造函数,则ASP.NET Core使用非默认构造函数

为什么.NET Core DI首选构造函数而不是无参数构造函数接受IEnumerable <T>?

在ASP.NET MVC Core控制器的构造函数中设置ViewBag属性

如何在新的ASP.NET Core中调用Web API非默认构造函数

具有多个构造函数的ASP .Net Core Web API依赖注入类

如何将DbContext注入ASP.NET Core中的存储库构造函数

ASP.Net Core中的简单服务注入不会调用构造函数

ASP.NET Core 依赖注入单个聚合类而不是多个单独的构造函数注入

从静态工厂类访问ASP.NET Core DI容器

如何从类访问Asp.net Core DI容器

具有依赖瞬态的 ASP.NET Core DI

使用ASP.NET Core DI注入工厂Func

ASP.NET Core:带条件的 DI 服务

在ConfigureServices中使用ASP.NET Core DI解决实例

无法使用 ASP.NET Core DI 注入委托

直接使用ASP.NET Core DI访问容器

带有DI的HtmlSanitizer + ASP.NET Core 2

ASP.NET Core Web App DI错误-无法构造某些服务(验证服务描述符时出错

.NET Core 2和DI-在构造函数中使用来自appsettings.json的值?

MassTransit和.NET Core DI-如何使用无参数构造函数解决依赖关系?

在.NET Core WebApp中构建服务层。构造函数DI不起作用

在ASP.NET 5中使用DI调用构造函数时解析依赖性