将多个实现注册到同一接口

时间:2019-07-10 13:38:21

标签: c# dependency-injection .net-core asp.net-core-webapi

我有一个public function verify() { $this->load->model('student/Studentinfo_model'); $check = $this->Studentinfo_model->validate(); if ($check) { $this->session->set_userdata('logged_in', TRUE); $this->session->set_userdata('username', $username); $user=$this->Studentinfo_model->validate(); redirect('student/dashboard'); } else { redirect('student'); } } public function dashboard() { if ($this->session->userdata('logged_in')) { $this->load->view('login-templates/header'); $this->load->view('student/dashboard'); print_r($this->session->all_userdata()); } else { redirect(site_url(student)); } } 类,该类用于与Azure blob存储进行交互。它实现了一个接口BlobStorageRepository

我需要使用两个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);

编辑:我的问题不是How to register multiple implementations of the same interface in Asp.Net Core?的重复,因为我想在添加服务时即private readonly IBlobStorageRepository _blobStorageRepository; private readonly IBlobStorageRepository _quarantineBlobStorageRepository; public DocumentService(IBlobStorageRepository blobStorageRepository, IBlobStorageRepository quarantineBlobStorageRepository) { _blobStorageRepository = blobStorageRepository; _quarantineBlobStorageRepository = quarantineBlobStorageRepository; } 传递实例化的类,而不能将实例化的类传递给services.AddSingleton<IBlobStorageRepository>(blobRepository)

3 个答案:

答案 0 :(得分:1)

不幸的是,我在嵌入式ASP.NET Core DI容器中找不到“命名实例”功能。在Autofac中,您可以使用Named and Keyed Services

根据您的情况,您可以执行以下操作:

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];
    }
}

答案 1 :(得分:1)

开箱即用,您所能做的就是使用以下命令注入接口的 all 个实例:

 WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off

(flow) hao@Hao:~/rllab-multiagent/rllab/viskit$ python frontend.py ~/rllab-multiagent/data/local/hao-stabilizing-highway-0.100/hao_stabilizing_highway_0.100_2019_07_09_20_01_57_0001
Importing data from ['/home/hao/rllab-multiagent/data/local/hao-stabilizing-highway-0.100/hao_stabilizing_highway_0.100_2019_07_09_20_01_57_0001']...
Reading /home/hao/rllab-multiagent/data/local/hao-stabilizing-highway-0.100/hao_stabilizing_highway_0.100_2019_07_09_20_01_57_0001/progress.csv
Reading /home/hao/rllab-multiagent/data/local/hao-stabilizing-highway-0.100/hao_stabilizing_highway_0.100_2019_07_09_20_01_57_0001/gym_log/progress.csv
[Errno 2] No such file or directory: '/home/hao/rllab-multiagent/data/local/hao-stabilizing-highway-0.100/hao_stabilizing_highway_0.100_2019_07_09_20_01_57_0001/gym_log/progress.csv'
Done! View http://localhost:5000 in your browser
 * Serving Flask app "frontend" (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off
Traceback (most recent call last):
  File "frontend.py", line 580, in <module>
    app.run(host='0.0.0.0', port=args.port, debug=args.debug)
  File "/home/hao/anaconda3/envs/flow/lib/python3.5/site-packages/flask/app.py", line 990, in run
    run_simple(host, port, self, **options)
  File "/home/hao/anaconda3/envs/flow/lib/python3.5/site-packages/werkzeug/serving.py", line 1009, in run_simple
    inner()
  File "/home/hao/anaconda3/envs/flow/lib/python3.5/site-packages/werkzeug/serving.py", line 962, in inner
    fd=fd,
  File "/home/hao/anaconda3/envs/flow/lib/python3.5/site-packages/werkzeug/serving.py", line 805, in make_server
    host, port, app, request_handler, passthrough_errors, ssl_context, fd=fd
  File "/home/hao/anaconda3/envs/flow/lib/python3.5/site-packages/werkzeug/serving.py", line 698, in __init__
    HTTPServer.__init__(self, server_address, handler)
  File "/home/hao/anaconda3/envs/flow/lib/python3.5/socketserver.py", line 440, in __init__
    self.server_bind()
  File "/home/hao/anaconda3/envs/flow/lib/python3.5/http/server.py", line 138, in server_bind
    socketserver.TCPServer.server_bind(self)
  File "/home/hao/anaconda3/envs/flow/lib/python3.5/socketserver.py", line 454, in server_bind
    self.socket.bind(self.server_address)
OSError: [Errno 98] Address already in use

然后,您需要自行决定如何为要设置的每个ivar从列表中拉出正确的实例。

在这种情况下,通常最好创建一个工厂类并注入它。例如,您可能有一个public MyClass(List<IBlobStorageRepository> repos) ,并提供了一种返回所需实例的存储库实例的方法。那可能是方法,属性等。这取决于您。关键是工厂要协调逻辑,以管理存储库并提供API来检索正确的存储库。

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

答案 2 :(得分:0)

供以后参考-我结合使用mtkachenko和Chris Pratt的答案来解决此问题:

创建了BlobStorageRepositoryFactory

public enum BlobStorageRepositoryType
{
    Core,
    Quarantine
}

public interface IBlobStorageRepositoryFactory
{
    void Register(BlobStorageRepositoryType type, IBlobStorageRepository blobRepository);
    IBlobStorageRepository Resolve(BlobStorageRepositoryType type);
}

public class BlobStorageRepositoryFactory : IBlobStorageRepositoryFactory
{
    private readonly Dictionary<BlobStorageRepositoryType, IBlobStorageRepository> _blobRepositories = new Dictionary<BlobStorageRepositoryType, IBlobStorageRepository>();

    public void Register(BlobStorageRepositoryType type, IBlobStorageRepository blobRepository)
    {
        _blobRepositories[type] = blobRepository;
    }

    public IBlobStorageRepository Resolve(BlobStorageRepositoryType type)
    {
        return _blobRepositories[type];
    }
}

然后进入我的Startup.cs

var blobStorageRepositoryFactory = new BlobStorageRepositoryFactory();
blobStorageRepositoryFactory.Register(BlobStorageRepositoryType.Core, GetBlobStorageRepository(_appSettings.BlobStorageAccountName, _appSettings.BlobStorageAccountKey));
blobStorageRepositoryFactory.Register(BlobStorageRepositoryType.Quarantine, GetBlobStorageRepository(_appSettings.QuarantineBlobStorageAccountName, _appSettings.QuarantineBlobStorageAccountKey));
services.AddSingleton<IBlobStorageRepositoryFactory>(blobStorageRepositoryFactory);

private static BlobStorageRepository GetBlobStorageRepository(string accountName, string accountKey)
{
    var storageCredentials = new StorageCredentials(accountName, accountKey);
    var cloudBlobStorageAccount = new CloudStorageAccount(storageCredentials, true);
    var cloudBlobClient = cloudBlobStorageAccount.CreateCloudBlobClient();
    var blobRepository = new BlobStorageRepository(cloudBlobClient);
    return blobRepository;
}

最后为我服务:

private readonly IBlobStorageRepository _blobStorageRepository;
private readonly IBlobStorageRepository _quarantineBlobStorageRepository;

public DocumentService(IBlobStorageRepositoryFactory blobStorageRepositoryFactory)
{
    _blobStorageRepository = blobStorageRepositoryFactory.Resolve(BlobStorageRepositoryType.Core);
    _quarantineBlobStorageRepository = blobStorageRepositoryFactory.Resolve(BlobStorageRepositoryType.Quarantine);
}