簡體   English   中英

將IOptions <>注入靜態類

[英]Injecting IOptions<> to static 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)':靜態構造函數上不允許使用訪問修飾符

'Encrypter.Encrypter(IOptions)':靜態構造函數必須是無參數的

可憐的設計選擇使該類靜態。

您正在經歷與將其與依賴項注入一起使用相關的挑戰。 靜電和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>();

不,這是不可能的。 首先,您的靜態構造函數根本不能具有訪問修飾符( public )或參數。 首次訪問靜態類時,CLR會調用靜態構造函數。 請參閱msdn

由於這是由CLR調用的,因此您永遠無法調用,因此您的DI框架也不能調用它。 您應該使用單例並將其注冊為服務,就像其他任何實例化類一樣。

它違反了DI,但前提是在使用Encrypter類之前已配置了DI,則可以對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>>();
    }
}

...但是請不要這樣做。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM