.net - 如何创建单例以依赖注入(inject)Azure存储客户端和容器

标签 .net azure dependency-injection singleton azure-storage

我有一个类,它有一个执行 Azure 存储操作的方法,目前,我每次调用它时都会创建 StorageContainer、BlobClient 和 Container:

private readonly IAzureStorageConfig _config;

public SaveImageBlob(IAzureStorageConfig config)
{
    _config = config;
}

public async Task<T> ExecuteAsync(ImageSaveInput input)
{

    //get the storage account from the connection string
    CloudStorageAccount storageAccount = CloudStorageAccount.Parse(_config.ConnectionString);

    //instantiate the client
    CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();

    //set the container
    CloudBlobContainer container = blobClient.GetContainerReference(_config.ImagesContainerName);

    //... do things and stuff
}

现在,我想将其从 SaveImageBlob.ExecuteAsync 方法中删除,并将其依赖项注入(inject)到类中,以便 Azure 存储项仅实例化一次。

我目前有这样的界面:

namespace Domain.Interfaces
{
    public interface IAzureStorage
    {
        CloudStorageAccount StorageAccount { get; }

        CloudBlobClient BlobClient { get; }

        CloudBlobContainer Container { get; }
    }
}

现在,我对如何实现该接口(interface)一无所知。

一旦实现了该接口(interface),我想我会将 SaveImageBlob.ExecuteAsync 方法更改为:

private readonly IAzureStorageConfig _config;
private readonly IAzureStorage _storage;

public SaveImageBlob(IAzureStorageConfig config,
                     IAzureStorage storage)
{
    _config = config;
    _storage = storage;
}

public async Task<T> ExecuteAsync(ImageSaveInput input)
{

    //now, since I don't have to create an instance of the storageAccount, blobClient, and container, I can just access them from _storage
    //create the blockBlob
    CloudBlockBlob blockBlob = _storage.Container.GetBlockBlobReference(input.BlobUrl); 

    //... do things and stuff with a Stream (doesn't really matter)

    //upload the blob
    blockBlob.UploadFromStreamAsync(stream);

    //do more things and stuff and return something 
}

我只需要知道如何实现接口(interface),该接口(interface)允许我将 AzureStorage 类作为单例注入(inject)到 SaveImageBlob 中。这并不重要,但为了后代,我使用 Autofac 进行 DI。

最佳答案

单例的基本思想由一个私有(private)静态实例变量和一个公共(public)静态实例属性组成,该属性可以线程安全地检查实例变量是否已设置,并设置它如果不是,则返回它。

using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Blob;
using System;

public sealed class AzureStorage
{
    private static volatile AzureStorage instance;
    private static object syncRoot = new Object();

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

    private AzureStorage()
    {
        StorageAccount = CloudStorageAccount.Parse(_config.ConnectionString);

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

        //set the container
        Container = BlobClient.GetContainerReference(_config.ImagesContainerName);

    }

    public static AzureStorage Instance
    {
        get
        {
            if (instance == null)
            {
                lock (syncRoot)
                {
                    if (instance == null)
                        instance = new AzureStorage();
                }
            }

            return instance;
        }
    }
}

留给读者的练习是提供配置。

关于.net - 如何创建单例以依赖注入(inject)Azure存储客户端和容器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45067709/

相关文章:

.net - 将文件夹同步到 S3 - C# 库

azure - 保护任务免遭 Azure Pipeline 中的修改

适用于多个 WebApi 端点的 Azure AD 承载 token ?

c# - .NET WS 客户端中可空类型的问题

c# - 在 .NET 中我应该为 128 位数字使用什么类型?

azure - 用户无需电子邮件而只需电话号码即可注册 Azure AD B2C

spring - 在 Spring 中实例化泛型类 bean 的问题

c# - 需要参数的对象的依赖注入(inject)

c# - 在服务类或单独的关注点中继承存储库?

c# - MemoryMappedFile.CreateOrOpen 抛出句柄无效