依赖注入模式如何在开始时初始化静态变量class
Dependency injection pattern how to initialize variables of static class at beginning
我已经使用依赖注入大约 6 个月了,有时我不知道如何以优雅的方式处理这种情况。
假设我想要一个 class 来存储我所有的应用程序设置。这个 class 只在开始时初始化。
请告诉我如何执行想法 1(因为我认为这是 classic 方式)以及想法 2 是否是有效模式或是否有更好的选择。
想法一:
使这个 class 静态,因为它的变量只被初始化,之后一切都保持只读。这个问题是我不知道在哪里初始化这个 class 的变量。要初始化其中一个变量,需要解密密码,这需要使用 IEncryption
接口。
我想在主程序实际启动之前初始化这些静态变量(因此最好在 Startup.cs
中)。我不能那样做,因为我无法在 DI 容器 class 中获得 IEncryption 的实现,或者至少我不知道一种优雅的方式来获得它。这应该如何用静态 class 完成?我应该在 Startup 和实际程序逻辑之间创建另一个“中间件”,以便我可以初始化静态变量吗?
如果我没弄错的话,只有简单数据 class即使在使用 DI 模式时,应用程序范围内的也可以是静态对象
想法二:
现在我不知道它是否有名字或是否曾经使用过。这只是我想出的东西,对我来说似乎是一个很好的解决方案,但可能有一个我不知道的替代方案使它毫无用处。
如果我不是将此 class 设为静态,而是将其设为普通 class 并在 class 构造函数中初始化所有静态变量,会怎样?
所以像这样:
public ClientData(IConfiguration configuration, IEncryption encryption)
{
var section = configuration.GetSection(nameof(ClientData));
EdgeUrl = section.GetValue<string>(nameof(EdgeUrl));
EdgeAuthUrl = section.GetValue<string>(nameof(EdgeAuthUrl));
Username = section.GetValue<string>(nameof(Username));
Password = encryption.Decrypt(section.GetValue<string>(nameof(Password)));
OrganizationKey = section.GetValue<string>(nameof(OrganizationKey));
}
public string EdgeUrl { get; }
public string EdgeAuthUrl { get; }
public string Username { get; }
public string Password { get; }
public string OrganizationKey { get; }
然后我通过构造函数注入 IEncryption。
我肯定会推荐第二种方法,除了您应该将属性保留为常规属性,而不是静态字段或属性。
您应该能够在 DI 容器中将其注册为 'singleton'。这确保只创建一个实例。因此,从 'is only one' 的意义上说,它是静态的,但仅在 DI 容器的上下文中,而不是在整个过程中。这允许更大的灵活性,例如,如果您希望应用程序的不同部分使用不同的配置。
这将需要将 class 注入到每个使用它的地方。幸运的是,DI 容器应该使这变得微不足道。
我已经使用依赖注入大约 6 个月了,有时我不知道如何以优雅的方式处理这种情况。
假设我想要一个 class 来存储我所有的应用程序设置。这个 class 只在开始时初始化。
请告诉我如何执行想法 1(因为我认为这是 classic 方式)以及想法 2 是否是有效模式或是否有更好的选择。
想法一:
使这个 class 静态,因为它的变量只被初始化,之后一切都保持只读。这个问题是我不知道在哪里初始化这个 class 的变量。要初始化其中一个变量,需要解密密码,这需要使用 IEncryption
接口。
我想在主程序实际启动之前初始化这些静态变量(因此最好在 Startup.cs
中)。我不能那样做,因为我无法在 DI 容器 class 中获得 IEncryption 的实现,或者至少我不知道一种优雅的方式来获得它。这应该如何用静态 class 完成?我应该在 Startup 和实际程序逻辑之间创建另一个“中间件”,以便我可以初始化静态变量吗?
如果我没弄错的话,只有简单数据 class即使在使用 DI 模式时,应用程序范围内的也可以是静态对象
想法二:
现在我不知道它是否有名字或是否曾经使用过。这只是我想出的东西,对我来说似乎是一个很好的解决方案,但可能有一个我不知道的替代方案使它毫无用处。
如果我不是将此 class 设为静态,而是将其设为普通 class 并在 class 构造函数中初始化所有静态变量,会怎样?
所以像这样:
public ClientData(IConfiguration configuration, IEncryption encryption)
{
var section = configuration.GetSection(nameof(ClientData));
EdgeUrl = section.GetValue<string>(nameof(EdgeUrl));
EdgeAuthUrl = section.GetValue<string>(nameof(EdgeAuthUrl));
Username = section.GetValue<string>(nameof(Username));
Password = encryption.Decrypt(section.GetValue<string>(nameof(Password)));
OrganizationKey = section.GetValue<string>(nameof(OrganizationKey));
}
public string EdgeUrl { get; }
public string EdgeAuthUrl { get; }
public string Username { get; }
public string Password { get; }
public string OrganizationKey { get; }
然后我通过构造函数注入 IEncryption。
我肯定会推荐第二种方法,除了您应该将属性保留为常规属性,而不是静态字段或属性。
您应该能够在 DI 容器中将其注册为 'singleton'。这确保只创建一个实例。因此,从 'is only one' 的意义上说,它是静态的,但仅在 DI 容器的上下文中,而不是在整个过程中。这允许更大的灵活性,例如,如果您希望应用程序的不同部分使用不同的配置。
这将需要将 class 注入到每个使用它的地方。幸运的是,DI 容器应该使这变得微不足道。