多个C#通道,相同类型,不同名称

问题描述 投票:0回答:2

在 C# 中使用通道时,我想运行具有相同基本类型的多个通道,但这会导致 DI 出现问题。比如说

我想要一个高优先级通道和一个中优先级通道,两者都是问题类型。因此将其设置为 DI 它看起来像

services.AddSingleton(channel.CreateUnbounded<Issue>()) // high priority
services.AddSingleton(channel.CreateUnbounded<Issue>()) // normal priority?


public async Task<bool> CreateHighPriorityIssues(Channel<Issue> channel) {}

public async Task<bool> CreateNormalPriorityIssues(Channel<Issue> channel) {}

上面的方法显然行不通,那么我该如何在不重构所有基类的情况下进行呢?

我能想到的唯一其他选择是实现某种工厂方法。

c# asp.net-core .net-core channel
2个回答
1
投票

根据研究,使用 Microsoft 的内置 DI 框架并没有简单的方法来做到这一点,尽管该框架易于使用,但功能并不像某些第三方 DI 框架那样丰富。

为此,我决定改用 Autofac,它为我提供了通过命名服务调用正确服务所需的灵活性。

https://autofac.readthedocs.io/en/latest/advanced/keyed-services.html


0
投票

你能不能简单地添加两个接口:

IIssueHighPriority { //members needed from Issue }

IIssueLowPriority { //members needed from Issue }

将两个接口应用到Issue类。

public class Issue : IIssueHighPriority, IIssueLowPriority

在 Di 中设置两个通道:

services.AddSingleton(channel.CreateUnbounded<IIssueHighPriority>()) 
services.AddSingleton(channel.CreateUnbounded<IIssueLowPriority>()) 

您的“上游服务”可以决定优先级,并排队到正确的通道。

if(needToProcessAsPriority)
   channelWriterHighPriority.TryWrite(issue);
else
   channelWriterLowPriority.TryWrite(issue);

worker 服务可以在其构造函数中指定两个 Channel,它将通过 DI 注入,并可以根据需要处理它们。

public class WorkerService : BackgroundService
{
    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
       while (!stoppingToken.IsCancellationRequested)
       {
          //Process from both Channels as required:
          while (await highPriorityQueueReader.WaitToReadAsync(stoppingToken))  
          {
              //do important things
          }

          while (await lowPriorityQueueReader .WaitToReadAsync(stoppingToken))  
          {
              //do less important things
          }
       }
    }
    
    public WorkerService(Channel<IIssueHighPriority> highPriority, Channel<IIssueLowPriority> lowPriority)
    {
        highPriorityQueueReader = highPriority.Reader;
        lowPriorityQueueReader = lowPriority.Reader;
    }
    ChannelReader<IIssueHighPriority> highPriorityQueueReader { get; }
    ChannelReader<IIssueLowPriority> lowPriorityQueueReader { get; } 
}
© www.soinside.com 2019 - 2024. All rights reserved.