Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用相同接口但不同构造函数参数值注册多个单例_C#_Dependency Injection_.net Core 3.1_Azure Servicebus Topics - Fatal编程技术网

C# 使用相同接口但不同构造函数参数值注册多个单例

C# 使用相同接口但不同构造函数参数值注册多个单例,c#,dependency-injection,.net-core-3.1,azure-servicebus-topics,C#,Dependency Injection,.net Core 3.1,Azure Servicebus Topics,我陷入困境,需要一些建议或解决办法 具有ASP.NET核心3.1的web API Startup.cs services.AddSingleton<ITopicClient>(s => new TopicClient({connectionstring},{topic})); 我需要向不同的主题发送消息。我想在startup.cs中注册具有不同主题名称的服务。我想重新使用topicClient连接 AddSingleton(s=>newtopicClient({connect

我陷入困境,需要一些建议或解决办法

具有ASP.NET核心3.1的web API

Startup.cs

services.AddSingleton<ITopicClient>(s => new TopicClient({connectionstring},{topic}));
我需要向不同的主题发送消息。我想在startup.cs中注册具有不同主题名称的服务。我想重新使用topicClient连接

AddSingleton(s=>newtopicClient({connectionstring},{topic1})

AddSingleton(s=>newtopicClient({connectionstring},{topic2})

如何通过使用相同接口注册相同类型的单例实例来实现这一点


提前谢谢你

您已经可以将多个实例注册为同一接口,因此当您注册时:

services.AddSingleton<ITopicClient>(_ => new TopicClient("topic1"));
services.AddSingleton<ITopicClient>(_ => new TopicClient("topic2"));
如果需要所有实例,则应解析/注入
IEnumerable

class主题存储库
{
公共主题存储库(IEnumerable客户端)
{
//客户端包含topic1和topic2
}
}

您可以使用一个客户端解析程序,该解析程序使用一个围绕客户端的包装器来保存已注册的客户端。 首先在您的客户机周围创建一个包装器,使用名称或枚举说明如何解析它。由于我不喜欢神奇的字符串,我决定在示例中使用枚举

// Wrapper for your TopicClients
public interface ICustomTopicClient
{
    public ITopicClient TopicClient { get; }
    public TopicName TopicName { get; }
}

// Implement the ICustomTopicClient interface
public class CustomTopicClient : ICustomTopicClient
{
    public ITopicClient TopicClient { get; }
    public TopicName TopicName { get; }
    
    public CustomTopicClient(ITopicClient topicClient, TopicName topicName)
    {
        TopicClient = topicClient;
        TopicName = topicName;
    }
}

// Enum for how to resolve the requested TopicClient
public enum TopicName
{
    Topic1 = 0,
    Topic2 = 1
}

// Register all ICustomTopicClients in your container
services.AddSingleton<ICustomTopicClient>(s => new CustomTopicClient(new TopicClient({connectionstring},{topic}), TopicName.Topic1));
services.AddSingleton<ICustomTopicClient>(s => new CustomTopicClient(new TopicClient({connectionstring},{topic2}), TopicName.Topic2));

您可以使用相同的模式并使用IQueueClients扩展解析器。并添加一个resolve方法,通过QueueName枚举返回IQueueClient。

您不需要为每个主题提供服务,你需要的是一个连接工厂,负责管理你的单个连接,然后你将其注入到你的服务中并调用它来为你返回连接。或者为每个主题创建一个类型,并为每个主题注册一个Topic123TopicClient。像数据库连接字符串一样,你的应用程序可能会使用一小部分固定的主题。有没有其他方法可以实现,因为目前我只需要5个主题的TopicClient实例,但它可能会增长。?
services.AddSingleton<ITopicClient>(_ => new TopicClient("topic1"));
services.AddSingleton<ITopicClient>(_ => new TopicClient("topic2"));
// instance = topic2
var instance = container.GetService<ITopicClient>();
class TopicRepository
{
    public TopicRepository(IEnumerable<ITopicClient> clients)
    {
        // clients contains topic1 and topic2
    }
}
// Wrapper for your TopicClients
public interface ICustomTopicClient
{
    public ITopicClient TopicClient { get; }
    public TopicName TopicName { get; }
}

// Implement the ICustomTopicClient interface
public class CustomTopicClient : ICustomTopicClient
{
    public ITopicClient TopicClient { get; }
    public TopicName TopicName { get; }
    
    public CustomTopicClient(ITopicClient topicClient, TopicName topicName)
    {
        TopicClient = topicClient;
        TopicName = topicName;
    }
}

// Enum for how to resolve the requested TopicClient
public enum TopicName
{
    Topic1 = 0,
    Topic2 = 1
}

// Register all ICustomTopicClients in your container
services.AddSingleton<ICustomTopicClient>(s => new CustomTopicClient(new TopicClient({connectionstring},{topic}), TopicName.Topic1));
services.AddSingleton<ICustomTopicClient>(s => new CustomTopicClient(new TopicClient({connectionstring},{topic2}), TopicName.Topic2));
public interface IMessageClientResolver
{
    ITopicClient ResolveClient(TopicName name);
}

public class MessageClientResolver : IMessageClientResolver
{
    private readonly Dictionary<TopicName, ITopicClient> topicClients;

    public MessageClientResolver(IEnumerable<ICustomTopicClient> clients)
    {
         topicClients = clients.ToDictionary(k => k.TopicName, v => v.TopicClient);
    }

    public ITopicClient ResolveClient(TopicName name)
    {
        topicClients.TryGetValue(name, out var client);
        if (client is null)
            throw new ArgumentException(nameof(client));

        return client;
    }
}
services.AddSingleton<IMessageClientResolver, MessageClientResolver>();
public class Foo
{
    private readonly ITopicClient topicClient;
    private readonly ITopicClient topicClient2;

    public Foo(IMessageClientResolver clientResolver)
    {
        topicClient = clientResolver.ResolveClient(TopicName.Topic1);
        topicClient2 = clientResolver.ResolveClient(TopicName.Topic2);
    }
}