将 IOptions<> 注入静态 class
Injecting IOptions<> to static class
我想将 class 保持为静态。是否有任何解决方法可以在不修改访问修饰符的情况下注入 IOptions<EncryptionSettings>
?
public static class Encrypter
{
private static readonly Encoding encoding = Encoding.UTF8;
private static readonly EncryptionSettings _encryptionSettings;
public static Encrypter(IOptions<EncryptionSettings> encryptionSettings)
{
_encryptionSettings = encryptionSettings.Value;
}
public static string Encrypt(string plainText)
{
(...)
}
public static string Decrypt(string plainText)
{
(...)
}
static byte[] HmacSHA256(String data)
{
(...)
}
}
'Encrypter.Encrypter(IOptions)':
access modifiers are not allowed on static constructors
'Encrypter.Encrypter(IOptions)':
a static constructor must be parameterless
不,这不可能。首先,您的静态构造函数根本不能有访问修饰符(public
)或参数。第一次访问静态 class 时,CLR 会调用静态构造函数。 (See msdn)
由于这是由 CLR 调用的,您永远无法调用它,因此您的 DI 框架也无法调用它。您应该使用单例并将其注册为任何其他实例化的服务 class.
它违反了 DI,但如果你的 DI 在你的 Encrypter
class 被使用之前配置,那么你可以使用对你的 DI 容器的静态引用:
public static class Encrypter
{
private static readonly EncryptionSettings _encryptionSettings;
static Encrypter()
{
if( IoC.Instance == null ) throw new InvalidOperationException( "IoC must be initialized before static members of Encrypter are used." );
_encryptionSettings = IoC.Instance.GetService<IOptions<EncryptionSettings>>();
}
}
...但请不要这样做。
糟糕的设计选择使 class 静态。
并且您正在经历与尝试将其与依赖注入一起使用相关的挑战。静电和 DI 不能很好地混合,应尽可能避免。
将所需的功能封装在抽象背后。
public interface IEncrypter {
string Encrypt(string plainText);
string Decrypt(string plainText);
}
并实施
public class Encrypter : IEncrypter {
private static readonly Encoding encoding = Encoding.UTF8;
private readonly EncryptionSettings _encryptionSettings;
public Encrypter(IOptions<EncryptionSettings> encryptionSettings) {
_encryptionSettings = encryptionSettings.Value;
}
public string Encrypt(string plainText) {
//(...)
}
public string Decrypt(string plainText) {
//(...)
}
static byte[] HmacSHA256(String data) {
//(...)
}
}
现在这将允许加密抽象 IEncrypter
根据需要连同它自己的依赖项一起注入。即 IOptions<TOption>
.
如果打算成为唯一的加密服务,则在启动时将其注册为单例
services.AddSingleton<IEncrypter, Encrypter>();
我想将 class 保持为静态。是否有任何解决方法可以在不修改访问修饰符的情况下注入 IOptions<EncryptionSettings>
?
public static class Encrypter
{
private static readonly Encoding encoding = Encoding.UTF8;
private static readonly EncryptionSettings _encryptionSettings;
public static Encrypter(IOptions<EncryptionSettings> encryptionSettings)
{
_encryptionSettings = encryptionSettings.Value;
}
public static string Encrypt(string plainText)
{
(...)
}
public static string Decrypt(string plainText)
{
(...)
}
static byte[] HmacSHA256(String data)
{
(...)
}
}
'Encrypter.Encrypter(IOptions)': access modifiers are not allowed on static constructors
'Encrypter.Encrypter(IOptions)': a static constructor must be parameterless
不,这不可能。首先,您的静态构造函数根本不能有访问修饰符(public
)或参数。第一次访问静态 class 时,CLR 会调用静态构造函数。 (See msdn)
由于这是由 CLR 调用的,您永远无法调用它,因此您的 DI 框架也无法调用它。您应该使用单例并将其注册为任何其他实例化的服务 class.
它违反了 DI,但如果你的 DI 在你的 Encrypter
class 被使用之前配置,那么你可以使用对你的 DI 容器的静态引用:
public static class Encrypter
{
private static readonly EncryptionSettings _encryptionSettings;
static Encrypter()
{
if( IoC.Instance == null ) throw new InvalidOperationException( "IoC must be initialized before static members of Encrypter are used." );
_encryptionSettings = IoC.Instance.GetService<IOptions<EncryptionSettings>>();
}
}
...但请不要这样做。
糟糕的设计选择使 class 静态。
并且您正在经历与尝试将其与依赖注入一起使用相关的挑战。静电和 DI 不能很好地混合,应尽可能避免。
将所需的功能封装在抽象背后。
public interface IEncrypter {
string Encrypt(string plainText);
string Decrypt(string plainText);
}
并实施
public class Encrypter : IEncrypter {
private static readonly Encoding encoding = Encoding.UTF8;
private readonly EncryptionSettings _encryptionSettings;
public Encrypter(IOptions<EncryptionSettings> encryptionSettings) {
_encryptionSettings = encryptionSettings.Value;
}
public string Encrypt(string plainText) {
//(...)
}
public string Decrypt(string plainText) {
//(...)
}
static byte[] HmacSHA256(String data) {
//(...)
}
}
现在这将允许加密抽象 IEncrypter
根据需要连同它自己的依赖项一起注入。即 IOptions<TOption>
.
如果打算成为唯一的加密服务,则在启动时将其注册为单例
services.AddSingleton<IEncrypter, Encrypter>();