xvd*_*iff 8 c# design-patterns factory dependency-injection cross-cutting-concerns
在大多数任意应用中,需要在所有可用层中解决许多交叉问题,例如日志记录,消息总线,配置.我注意到的是,在某些类中,如果使用IoC注入模块,它们往往会完全炸毁构造函数.
public class MyService : IService
{
public MyService(ILogger logger, IAppSettings settings, IEventBus eventBus...)
{
}
}
Run Code Online (Sandbox Code Playgroud)
对于构造函数过度注入的常见情况,我倾向于将关注点折射成紧密组合在一起的构建块,因此我在类中获得的依赖项更少.但是,对于交叉切割概念,这是不可能的.
在日志框架中,静态工厂/服务似乎非常流行,例如
// Application root
MyLoggerService.SetFactory(log4NetFactory);
// Somewhere
MyLoggerService.GetLogger("name") // returns Log4NetLogger created by Log4NetFactory.
Run Code Online (Sandbox Code Playgroud)
我的问题是:对于各种交叉切割的东西,这种方法是否很好?如果代码最终看起来像这样,有什么缺点:
public class MyService : IService
{
private readonly IReallyNeedThat _dependency;
public MyService(IReallyNeedThat dependency)
{
_dependency = dependency;
}
private readonly ILogger _logger = LoggerService.GetLogger("MyService");
private readonly IEventBus _eventBus = EventBusService.GetEventBus();
private readonly IConfiguration _configuration = ConfigurationService.GetConfiguration(Level.Roaming)
private readonly IExceptionHandler _exceptionHandler = ExceptionPolicy.GetHandler();
private readonly ITracer _tracer = TraceManager.GetDebugTracer();
}
Run Code Online (Sandbox Code Playgroud)
将依赖项移出构造函数并不能解决问题,因为您不会降低类具有的依赖项数量,并且您仍然违反单一责任原则和打开/关闭原则的可能性很大,导致您的代码难以测试,难以改变,难以维护.
相反,通常一个好的解决方案是将这些横切关注点从您的组件中拉出来,并将它们放入专为该交叉关注点而量身定制的组件中,并将该组件包裹在原始组件中.换句话说:创建装饰器.
这可能会强制您更改类的设计,因为当您没有通用抽象来定义相关服务集时,您将不得不为每个抽象定义一个装饰器,这将导致大量代码重复,这是几乎在所有情况下都很糟糕
因此,围绕命令/处理程序和查询/处理程序对系统进行建模,您将处于更好的位置.您可以使用您定义一次的通用装饰器来装饰每个业务逻辑,并在整个地方重复使用.这可以保持系统清洁,但仍然非常灵活.
如果您更喜欢TDD,您可以轻松猜出哪种方法更好.
通过依赖注入,您的代码变得更加(单元)可测试.您可以通过一些模拟框架注入依赖项,并创建您的单元测试,而不必担心.
但是对于静态工厂,由于您的工厂类(硬)连接到您的班级,而单元测试,您无法从课外注入它们.
DI对静态工厂的好处 -
并发开发 - 想想您正在使用的日志服务,这是由其他人构建的,您将对您的代码进行单元测试(并且您不关心日志服务的单元测试,因为您认为它应该是单元在你使用它时测试).你打击使用DI,使用模拟对象注入依赖并完成.
速度 - 在对您的课程进行单元测试时,您肯定不会希望它们花费很长时间(因此,它会让您在主要课程的每次更改时都能享用咖啡时间;)).您肯定希望单元测试在眨眼间运行并报告任何错误.依赖外部资源(例如网络/数据库,文件系统)的静态工厂需要时间.你最好使用DI,使用模拟对象并完成.
可测试性 - DI有助于将客户端与其依赖关系隔离开来(促进接口的使用),从而提高可测试性(通过使用模拟).
| 归档时间: |
|
| 查看次数: |
1585 次 |
| 最近记录: |