Mas*_*uri 4 c# dependency-injection
我一直在用DI制作简单的记录器类,但是我有一些问题。
这儿存在一个问题。如果我使用DI进行记录器课程。每当我使用它时,都应该这样使用它。
var logger = new LogService(new FileLogger());
logger.WriteLine("message");
Run Code Online (Sandbox Code Playgroud)
我想使其成为静态类,但是没有办法通过静态类中的构造函数注入依赖项。
所以,我这样改变它。
public static class LogService()
{
private static readonly ILoggable _logger;
static LogService()
{
_logger = new FileLogger();
}
}
Run Code Online (Sandbox Code Playgroud)
我觉得这很奇怪。这不是DI ..
没有将依赖项注入静态类的好方法吗?
谢谢。
Ste*_*ven 10
作为一种实践,依赖注入旨在引入抽象(或接缝)来消除易失性依赖。易失性依赖项是一个类或模块,除其他外,它可以包含不确定性行为,或者通常是我们可以替换或拦截的类或模块。有关volatile依赖关系的详细讨论,请参见本书的可免费下载的简介的1.3.2节。
因为您FileLogger写入磁盘,所以它包含不确定的行为。因此,您引入了ILoggable抽象。这样可以使使用者与实现分离FileLogger。
为了能够使消费者与其不稳定的依赖关系成功脱钩,我们需要将这种依赖关系注入消费者。共有三种常见模式可供选择:
构造器注入和属性注入都应用在 “ 合成根” 内部,并且要求使用者将依赖项存储在私有字段中,以便以后重用。这要求构造函数和属性是实例成员,即非静态的。静态构造函数不能具有任何参数,并且静态属性会导致Ambient Context反模式(请参见本书的第5.3章)和时间耦合。这阻碍了可测试性和可维护性。
方法注入,另一方面,被施加外的组合物根,它并没有存储任何提供的相关性,而仅仅使用它。因此,方法注入可以应用于实例方法和静态方法。在这种情况下,方法的使用者必须提供依赖性。但是,这的确意味着必须通过构造函数,属性或方法注入将自身提供给该依赖项。
您在其构造函数内部LogService创建的static的FileLogger示例是强耦合代码的一个很好的示例。这被称为Control Freak反模式(第5.1章),或者通常可以视为违反DIP。这与 DI 相反。
为了防止易失性依赖关系的强耦合,最好是使它成为LogService非静态的,并将其易失性依赖关系注入其唯一的公共构造函数中。
将依赖注入 (DI) 与静态类一起使用是没有意义的。而不是 DI,只需向您的静态类添加一个初始化方法并传入依赖项。
public static class LogService
{
private static ILoggable _logger;
public static ILoggable Logger
{
get
{
return _logger;
}
}
public static void InitLogger(ILoggable logger)
{
_logger = logger;
}
}
Run Code Online (Sandbox Code Playgroud)
要使用记录器,请确保先调用InitLogger():
LogService.InitLogger(new FileLogger());
LogService.Logger.WriteLine("message");
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8353 次 |
| 最近记录: |