向同一个接口注册多个实现

chr*_*ris 6 c# dependency-injection .net-core asp.net-core-webapi

我有一个BlobStorageRepository类用于与 Azure blob 存储交互。它实现一个接口IBlobStorageRepository

我需要使用两个实例,BlobStorageRepository但它们使用不同的凭据进行设置:

在我的Startup.cs

// Normal storage
var storageCredentials = new StorageCredentials(_appSettings.BlobStorageAccountName, _appSettings.BlobStorageAccountKey);
var cloudBlobStorageAccount = new CloudStorageAccount(storageCredentials, true);
var cloudBlobClient = cloudBlobStorageAccount.CreateCloudBlobClient();
var blobRepository = new BlobStorageRepository(cloudBlobClient);

// Quarantine storage
var quarantineStorageCredentials = new StorageCredentials(_appSettings.QuarantineBlobStorageAccountName, _appSettings.QuarantineBlobStorageAccountKey);
var quarantineCloudBlobStorageAccount = new CloudStorageAccount(quarantineStorageCredentials, true);
var quarantineCloudBlobClient = quarantineCloudBlobStorageAccount.CreateCloudBlobClient();
var quarantineBlobRepository = new BlobStorageRepository(quarantineCloudBlobClient);

services.AddSingleton<IBlobStorageRepository>(blobRepository);
services.AddSingleton<IBlobStorageRepository>(quarantineBlobRepository);
Run Code Online (Sandbox Code Playgroud)

如何配置上述内容,以便可以解析类中的依赖项并获取两个不同的实例,即:

private readonly IBlobStorageRepository _blobStorageRepository;
private readonly IBlobStorageRepository _quarantineBlobStorageRepository;

public DocumentService(IBlobStorageRepository blobStorageRepository, IBlobStorageRepository quarantineBlobStorageRepository)
{
    _blobStorageRepository = blobStorageRepository;
    _quarantineBlobStorageRepository = quarantineBlobStorageRepository;
}
Run Code Online (Sandbox Code Playgroud)

编辑:我的问题不是重复的如何在 Asp.Net Core 中注册同一接口的多个实现?因为我想在添加服务时传递实例化的类services.AddSingleton<IBlobStorageRepository>(blobRepository),即,您无法将实例化的类传递给serviceProvider.GetService<BlobStorageRepository>().

Chr*_*att 8

开箱即用,您所能做的就是使用以下方式注入接口的所有实例:

public MyClass(List<IBlobStorageRepository> repos)
Run Code Online (Sandbox Code Playgroud)

然后,您需要自己决定如何从要设置的每个 ivar 的列表中提取正确的实例。

在这种情况下,通常最好创建一个工厂类并注入它。例如,您可以提供BlobStorageRepositoryFactory一种方法来返回您需要的特定场景的存储库实例。这可以是方法、属性等。这取决于您。重点是工厂协调管理存储库和提供 API 来检索正确存储库的逻辑。

或者,您可以补充Microsoft.Extensions.DependencyInjection一个更强大的 DI 容器。支持的容器列表可以在以下位置找到: https: //github.com/aspnet/Extensions/tree/master/src/DependencyInjection


mtk*_*nko 5

不幸的是,我在嵌入式 ASP.NET Core DI 容器中找不到“命名实例”功能。在Autofac中,您可以使用命名和键控服务

在你的情况下,你可以这样做:

public enum RepoTypes { Blob, Quarantine }

...

public interface IRepoResolver
{
    //resolve using method
    IBlobStorageRepository GetRepo(RepoTypes rt);

    //resolve usnig indexer
    IBlobStorageRepository this[RepoTypes rt] { get; }
}

...

public sealed RepoResolver : IRepoResolver
{
    private readonly Dictionary<RepoTypes, IBlobStorageRepository> _repos;

    public RepoResolver()
    {
        _repos[RepoTypes.Blob] = new BlobStorageRepository(...);
        _repos[RepoTypes.Quarantine] = new BlobStorageRepository(...);
    }

    public IBlobStorageRepository GetRepo(RepoTypes rt) => _repos[rt];

    public IBlobStorageRepository this[RepoTypes rt] { get => _repos[rt]; }
}

...

services.AddSingleton<IRepoResolver, RepoResolver>();

...

public class Some
{
    public Some(IRepoResolver rr)
    {
        var blob1 = rr.GetRepo(RepoTypes.Blob);
        var blob2 = rr[RepoTypes.Blob];
    }
}
Run Code Online (Sandbox Code Playgroud)

  • @sureshrajput您可以在此处的最后一个答案中找到他的实现。但也请阅读我对答案的评论以了解缺点 (2认同)