使用设置注入 class 的多个实例
Injecting multiple instances of a class with settings
我在使用 Azure 存储时遇到了一些问题。我目前有一个很好的实现,但我想扩展它,以便我能够在一个解决方案中使用多个存储 accounts/containers。我无法理解如何做到这一点并且仍然允许依赖注入。我还需要能够传递定义连接字符串和容器名称的设置
这就是我目前的做法:
builder.Services.AddSingleton<IAzureStorageClient, AzureStorageClient>();
builder.Services.Configure<AzureStorageSettings>(configuration.GetSection("AzureStorageSettings"));
然后在构造函数中
public AzureStorageClient(IOptions<AzureStorageSettings> options)
{
var azureStorageSettings = options.Value;
var cloudStorageAccount = GetCloudStorageAccount(azureStorageSettings.ConnectionString);
_blobClient = cloudStorageAccount.CreateCloudBlobClient();
_blobContainer = GetBlobContainer(azureStorageSettings.ContainerName);
}
我读过很多提到使用命名注册的类似帖子,但我使用的是内置的 IoC 容器,它不允许这样做。我还看到帖子说要使用看起来不错的工厂,但我希望打包这个逻辑并在不同的解决方案之间共享它,而工厂解决方案需要大量配置,我想避免这些配置,以使包装易于使用消费。
更新:
我将设置设置为一个接口,以在每次需要时强制执行它,并且我使用通用 T 将其传递到我的存储客户端,如下所示:
public sealed class AzureStorageClient<T> : IAzureStorageClient<T> where T : class, IAzureStorageSettings, new()
public AzureStorageClient(IOptions<T> options)
{
var azureStorageSettings = options.Value;
var cloudStorageAccount = GetCloudStorageAccount(azureStorageSettings.ConnectionString);
_blobClient = cloudStorageAccount.CreateCloudBlobClient();
_blobContainer = GetBlobContainer(azureStorageSettings.ContainerName);
}
然后可以这样注入:
builder.Services.AddSingleton<IAzureStorageClient<SpecificStorageSettings>, AzureStorageClient<SpecificStorageSettings>>();
举个例子,你可以这样设置:
Settings.cs
using System;
using System.Collections.Generic;
using System.Text;
namespace UseDifferentSettings
{
public abstract class Settings
{
public abstract string connectingstring {
get;
}
public abstract string containername {
get;
}
public abstract string blobname {
get;
}
}
}
Setting1.cs
using System;
using System.Collections.Generic;
using System.Text;
namespace UseDifferentSettings
{
class Setting1 : Settings
{
string _connectingstring = "DefaultEndpointsProtocol=https;AccountName=xxx;EndpointSuffix=core.windows.net";
string _containername = "video1";
string _blobname = "test.txt";
public override string connectingstring
{
get { return _connectingstring; }
}
public override string containername
{
get { return _containername; }
}
public override string blobname
{
get { return _blobname; }
}
}
}
Setting2.cs
using System;
using System.Collections.Generic;
using System.Text;
namespace UseDifferentSettings
{
class Setting2 : Settings
{
private string _connectingstring = "DefaultEndpointsProtocol=https;AccountName=xxx;EndpointSuffix=core.windows.net";
private string _containername = "test";
private string _blobname = "test.txt";
public override string connectingstring
{
get { return _connectingstring; }
}
public override string containername
{
get { return _containername; }
}
public override string blobname
{
get { return _blobname; }
}
}
}
UploadToStorage.cs
using Azure.Storage.Blobs;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace UseDifferentSettings
{
public class UploadToStorage
{
Settings setting;
public UploadToStorage(Settings setting) {
this.setting = setting;
}
public void GoUpload() {
string connectingstring = setting.connectingstring;
string containername = setting.containername;
string blobname = setting.blobname;
string filecontent = "This is my test file content";
byte[] array = Encoding.ASCII.GetBytes(filecontent);
MemoryStream filestream = new MemoryStream(array);
BlobServiceClient blobServiceClient = new BlobServiceClient(connectingstring);
BlobContainerClient containerClient = blobServiceClient.GetBlobContainerClient(containername);
BlobClient blobClient = containerClient.GetBlobClient(blobname);
blobClient.Upload(filestream);
}
}
}
Program.cs(主要方法class)
using System;
namespace UseDifferentSettings
{
class Program
{
static void Main(string[] args)
{
Settings setting1 = new Setting1();
Settings setting2 = new Setting2();
UploadToStorage uploadtostorage = new UploadToStorage(setting1);
uploadtostorage.GoUpload();
Console.WriteLine("Hello World!");
}
}
}
我在使用 Azure 存储时遇到了一些问题。我目前有一个很好的实现,但我想扩展它,以便我能够在一个解决方案中使用多个存储 accounts/containers。我无法理解如何做到这一点并且仍然允许依赖注入。我还需要能够传递定义连接字符串和容器名称的设置
这就是我目前的做法:
builder.Services.AddSingleton<IAzureStorageClient, AzureStorageClient>();
builder.Services.Configure<AzureStorageSettings>(configuration.GetSection("AzureStorageSettings"));
然后在构造函数中
public AzureStorageClient(IOptions<AzureStorageSettings> options)
{
var azureStorageSettings = options.Value;
var cloudStorageAccount = GetCloudStorageAccount(azureStorageSettings.ConnectionString);
_blobClient = cloudStorageAccount.CreateCloudBlobClient();
_blobContainer = GetBlobContainer(azureStorageSettings.ContainerName);
}
我读过很多提到使用命名注册的类似帖子,但我使用的是内置的 IoC 容器,它不允许这样做。我还看到帖子说要使用看起来不错的工厂,但我希望打包这个逻辑并在不同的解决方案之间共享它,而工厂解决方案需要大量配置,我想避免这些配置,以使包装易于使用消费。
更新: 我将设置设置为一个接口,以在每次需要时强制执行它,并且我使用通用 T 将其传递到我的存储客户端,如下所示:
public sealed class AzureStorageClient<T> : IAzureStorageClient<T> where T : class, IAzureStorageSettings, new()
public AzureStorageClient(IOptions<T> options)
{
var azureStorageSettings = options.Value;
var cloudStorageAccount = GetCloudStorageAccount(azureStorageSettings.ConnectionString);
_blobClient = cloudStorageAccount.CreateCloudBlobClient();
_blobContainer = GetBlobContainer(azureStorageSettings.ContainerName);
}
然后可以这样注入:
builder.Services.AddSingleton<IAzureStorageClient<SpecificStorageSettings>, AzureStorageClient<SpecificStorageSettings>>();
举个例子,你可以这样设置:
Settings.cs
using System;
using System.Collections.Generic;
using System.Text;
namespace UseDifferentSettings
{
public abstract class Settings
{
public abstract string connectingstring {
get;
}
public abstract string containername {
get;
}
public abstract string blobname {
get;
}
}
}
Setting1.cs
using System;
using System.Collections.Generic;
using System.Text;
namespace UseDifferentSettings
{
class Setting1 : Settings
{
string _connectingstring = "DefaultEndpointsProtocol=https;AccountName=xxx;EndpointSuffix=core.windows.net";
string _containername = "video1";
string _blobname = "test.txt";
public override string connectingstring
{
get { return _connectingstring; }
}
public override string containername
{
get { return _containername; }
}
public override string blobname
{
get { return _blobname; }
}
}
}
Setting2.cs
using System;
using System.Collections.Generic;
using System.Text;
namespace UseDifferentSettings
{
class Setting2 : Settings
{
private string _connectingstring = "DefaultEndpointsProtocol=https;AccountName=xxx;EndpointSuffix=core.windows.net";
private string _containername = "test";
private string _blobname = "test.txt";
public override string connectingstring
{
get { return _connectingstring; }
}
public override string containername
{
get { return _containername; }
}
public override string blobname
{
get { return _blobname; }
}
}
}
UploadToStorage.cs
using Azure.Storage.Blobs;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace UseDifferentSettings
{
public class UploadToStorage
{
Settings setting;
public UploadToStorage(Settings setting) {
this.setting = setting;
}
public void GoUpload() {
string connectingstring = setting.connectingstring;
string containername = setting.containername;
string blobname = setting.blobname;
string filecontent = "This is my test file content";
byte[] array = Encoding.ASCII.GetBytes(filecontent);
MemoryStream filestream = new MemoryStream(array);
BlobServiceClient blobServiceClient = new BlobServiceClient(connectingstring);
BlobContainerClient containerClient = blobServiceClient.GetBlobContainerClient(containername);
BlobClient blobClient = containerClient.GetBlobClient(blobname);
blobClient.Upload(filestream);
}
}
}
Program.cs(主要方法class)
using System;
namespace UseDifferentSettings
{
class Program
{
static void Main(string[] args)
{
Settings setting1 = new Setting1();
Settings setting2 = new Setting2();
UploadToStorage uploadtostorage = new UploadToStorage(setting1);
uploadtostorage.GoUpload();
Console.WriteLine("Hello World!");
}
}
}