使用 Autofac 上的配置注册更多 AmazonS3Client

Registering more AmazonS3Client with configurations on Autofac

我将 AWSSDK.S3 添加到我的项目中,因为我想使用 S3FileInfo 以一种干净的方式访问 S3 上的文件,并且我在 Autofac 上注册了一个 AmazonS3Client 的实例以在我的服务中获取它。

在 Autofac 上注册是这样的:

builder.Register(context => {
    var credentials = new BasicAWSCredentials("accessKeyId", "SecretAccessKey");
    var config = new AmazonS3Config {
        RegionEndpoint = RegionEndpoint.GetBySystemName("regionEndpoint")
    };
    return new AmazonS3Client(credentials, config);
}).As<IAmazonS3>().SingleInstance();

关键是,如果我想添加更多配置以像这样访问不同帐户上的不同存储桶,我不能。 在 Autofac 上注册更多具有不同配置的 IAmazonS3 实例的最干净的方法是什么?

没有找到合适的答案,经过深思熟虑后我决定采用这种方法,可能不是很干净但它有效:

public interface IAmazonS3FirstConfig : IAmazonS3
{
}

public class AmazonS3ClientFirstConfig : AmazonS3Client, IAmazonS3FirstConfig
{
    public AmazonS3ClientFirstConfig(BasicAWSCredentials credentials, AmazonS3Config config)
        : base(credentials, config)
    {
    }
}

使用 ad-hoc class 和接口注册此配置,另外一对用于第二个配置。

有很多方法可以做你想做的事。这取决于您从哪里获得凭证。

如果您在构建 autofac 时知道凭据,则可以使用命名实例

    builder.Register(context => {
        var credentials = new BasicAWSCredentials("accessKeyId1", "SecretAccessKey1");
        var config = new AmazonS3Config {
            RegionEndpoint = RegionEndpoint.GetBySystemName("regionEndpoint")
        };
        return new AmazonS3Client(credentials, config);
    }).Named<IAmazonS3>("client1").SingleInstance();

    builder.Register(context => {
        var credentials = new BasicAWSCredentials("accessKeyId2", "SecretAccessKey2");
        var config = new AmazonS3Config {
            RegionEndpoint = RegionEndpoint.GetBySystemName("regionEndpoint")
        };
        return new AmazonS3Client(credentials, config);
    }).Named<IAmazonS3>("client2").SingleInstance();

要解决它们,您可以使用 IIndex<String, IAmazonS3> 或在注册时使用 WithParameter 方法或使用 autofac 模块。

有关命名实例的更多信息可在文档中找到:Named and Keyed services

如果您在运行时拥有凭据,则可以解析工厂。假设 ServiceX 需要一个 IAmazonS3Client 实例,您可以依赖 Func<BasicAwsCredentials, AmazonS3Config, IAmazonS3Client> 并且 Autofac 将为您施展魔法。

public class ServiceX 
{
    public ServiceX(Func<BasicAwsCredentials, AmazonS3Config, IAmazonS3Client> factory)
    {
        this._amazonS3Factory = factory; 
    }
    private readonly Func<BasicAwsCredentials, AmazonS3Config, IAmazonS3Client> _amazonS3Factory; 

    public void Do()
    {
        IAmazonS3Client client = this._amazonS3FActory(credentials, config); 
        // do something with client
    }
}