为什么要通过HttpContext.RequestServices
或IServiceProvider
考虑不良做法来请求服务。我可以到处阅读此声明:
建议使用构造函数注入而不是使用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反模式的实现。
您试图通过将许多常见的依赖关系和通用的逻辑移到基类中来使控制器类变小,但这本身就是一种反模式,因为:
基类使用继承,而软件开发中的普遍共识是,您应该更喜欢Composition而不是继承。
由于您应该支持组合,因此这将自动导致依赖注入。如果没有基类,则立即发现违反“单一责任原则”的问题将变得更加容易,因为您的构造函数将获得更多的参数。再次注意,使用Service Locator时,依赖项的数量不会改变,它们的计数更难。
您应该接受一个事实,即构造器注入很容易导致构造器过度注入,因为这表明我们的课程做得太多,并且表明我们应该重新设计此类。
与其在基类中实现诸如日志记录,缓存和授权之类的横切关注点,不如使用组合实现它们。例如,您可以使用中间件,装饰器或拦截器将横切关注点应用于请求(或此类请求的特定服务)。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句