Внедрение зависимостей в экземпляр класса запечатанного класса

В настоящее время я пытаюсь создать запечатанный класс, который получает конфигурацию хранилища Azure через настройки, хранящиеся в JSON. Я регистрирую настройки в классе startup.cs, а затем внедряю их в конструктор. Проблема в том, что мне нужно инициировать один и тот же класс внутри класса, потому что это закрытый класс

public sealed class AzureFileStorage
{
    private static volatile AzureFileStorage instance;
    private static object syncRoot = new Object();
    private readonly AzureBlobSettings _azureBlobSettings;

    public CloudStorageAccount StorageAccount { get; private set; }
    public CloudBlobClient BlobClient { get; private set; }
    public CloudBlobContainer Container { get; private set; }

    public AzureFileStorage(IOptions<AzureBlobSettings> fbAuthSettingsAccessor)
    {
        _azureBlobSettings = fbAuthSettingsAccessor.Value;
        StorageAccount = CloudStorageAccount.Parse(_azureBlobSettings.BlobStorageConnectionString);

        //instantiate the client
        BlobClient = StorageAccount.CreateCloudBlobClient();

        //set the container
        Container = BlobClient.GetContainerReference(_azureBlobSettings.ContainerBlobAzureId);

    }

    public static AzureFileStorage Instance
    {
        get
        {
            if (instance == null)
            {
                lock (syncRoot)
                {

                    if (instance == null)
                        instance = new AzureFileStorage(????);
                }
            }

            return instance;
        }
    }
}

Как инициировать azurefilestorage, если azureblobsettings передаются через внедрение зависимостей.


person Pablo Corzo    schedule 23.11.2018    source источник
comment
Почему вы создаете статический экземпляр, если используете контейнер внедрения зависимостей? Стандартный способ справиться с этим — объявить тип как синглтон в контейнере.   -  person Mike Zboray    schedule 23.11.2018
comment
"Проблема в том, что мне нужно инициировать тот же класс внутри класса, потому что это запечатанный класс" — Вы, кажется, путаете запечатанный с статическим там. Это два совершенно не связанных между собой понятия.   -  person poke    schedule 25.11.2018


Ответы (1)


Как уже упоминалось комментатором, текущий дизайн плохо подходит для внедрения зависимостей.

Класс AzureFileStorage следует реорганизовать, чтобы удалить экземпляр синглтона и, кроме того, иметь собственную абстракцию.

public interface IAzureFileStorage {
    CloudStorageAccount StorageAccount { get; }
    CloudBlobClient BlobClient { get; }
    CloudBlobContainer Container { get; }
}

public sealed class AzureFileStorage : IAzureFileStorage {
    private readonly AzureBlobSettings _azureBlobSettings;


    public AzureFileStorage(IOptions<AzureBlobSettings> fbAuthSettingsAccessor) {
        _azureBlobSettings = fbAuthSettingsAccessor.Value;
        StorageAccount = CloudStorageAccount.Parse(_azureBlobSettings.BlobStorageConnectionString);

        //instantiate the client
        BlobClient = StorageAccount.CreateCloudBlobClient();

        //set the container
        Container = BlobClient.GetContainerReference(_azureBlobSettings.ContainerBlobAzureId);
    }

    public CloudStorageAccount StorageAccount { get; private set; }
    public CloudBlobClient BlobClient { get; private set; }
    public CloudBlobContainer Container { get; private set; }
}

И зарегистрирован как синглтон в сервисной коллекции.

public void ConfigureServices(IServiceCollection services) {

    //...

    service.AddSingleton<IAzureFileStorage, AzureFileStorage>();

    //...
}

Так что везде, где IAzureFileStorage явно вводится,

private readonly IAzureFileStorage fileStore;

public SomeClass(IAzureFileStorage fileStore) {
    this.fileStore = fileStore;
}

один и тот же экземпляр будет использоваться во всем приложении.

person Nkosi    schedule 24.11.2018