依赖注入模式如何在开始时初始化静态类的变量
Posted
技术标签:
【中文标题】依赖注入模式如何在开始时初始化静态类的变量【英文标题】:Dependency injection pattern how to initialize variables of static class at beginning 【发布时间】:2021-11-22 02:26:57 【问题描述】:我已经使用依赖注入大约 6 个月了,有时我不知道如何优雅地处理。
假设我想要一个类来存储我所有的应用设置。这个类只在开始时初始化。
请告诉我如何执行想法 1(因为我认为这是经典方式)以及想法 2 是否是有效模式或是否有更好的替代方案。
想法 1:
将这个类设为静态,因为它的变量只被初始化,之后一切都保持只读状态。这个问题是我不知道在哪里初始化这个类的变量。要初始化其中一个变量,需要解密密码,这需要使用IEncryption
接口。
我想在主程序实际启动之前初始化这些静态变量(所以最好在Startup.cs
中)。我不能这样做,因为我无法在 DI 容器类中获得 IEncryption 的实现,或者至少我不知道获得它的优雅方法。这应该如何使用静态类来完成?我应该在 Startup 和实际程序逻辑之间创建另一个“中间件”,我可以在其中初始化静态变量吗?
如果我没记错的话,即使使用 DI 模式,只有应用程序范围内的类才能成为静态对象
想法 2:
现在我不知道它是否有名称或是否曾经使用过。这只是我想出的东西,对我来说似乎是一个很好的解决方案,但可能有一个我不知道的替代方案使它无用。
如果我不将此类设为静态,而是将其设为普通类并在类构造函数中初始化所有静态变量,该怎么办。
所以是这样的:
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。
【问题讨论】:
为什么让它成为静态而不是作为单例注入?所以,是的,Idea 2 对我来说看起来不错 @Klamsi 太好了,谢谢。 【参考方案1】:我肯定会推荐第二种方法,除了您应该将属性保留为常规属性,并且没有静态字段或属性。
您应该能够在 DI 容器中将其注册为“单例”。这样可以确保只创建一个实例。因此,从“只有一个”的意义上说,这将是一种静态的,但仅在 DI 容器的上下文中,而不是在整个过程中。这允许更大的灵活性,例如,如果您希望应用程序的不同部分使用不同的配置。
这将要求将类注入到使用它的每个地方。幸运的是,DI 容器应该使这变得微不足道。
【讨论】:
这很棒。我确实将它注入到 DI 容器中,因为是的。我只是认为 DI 还有另一种方法,因为我在很多场合都听说过这样的静态类在使用 DI 模式时是可以的。我只是遇到了问题,因为我无法在静态类中注入 IEncryption,所以我真的不知道如何获得代码。所以我只是想出了第二种方法。我还听说你不应该用 DI 注入这样的类(注入我在“idea 2”中作为示例给出的类),因为它们只是没有真正逻辑的基本类,因此不是依赖项。 我也不明白为什么要删除属性并改用常规字段? @Matic Cavalleri,就像您在示例中所做的那样。您编写“在类构造函数中初始化所有静态变量”,这与您的示例相矛盾,因为您的示例中的属性不是静态的。他们不应该是。 你是对的,我打错了。以上是关于依赖注入模式如何在开始时初始化静态类的变量的主要内容,如果未能解决你的问题,请参考以下文章
在swift中,当应用程序进入后台时,如何使用依赖注入保存变量?