简体   繁体   English

如何通过Func发送一个方法来执行C#中的另一个方法?

[英]How to send a method to execute to another method in C# via Func?

I have a service-class that looks like: 我有一个服务类,看起来像:

class BillingService
{
    public void CheckBillingStatus(BillingOperationRequestDto dto)
    {
    }

    public void AnotherOperationOnBillings(BillingOperationRequestDto dto)
    {
    }
}

Also I have another class that listen to some queue from RabbitMq. 另外我还有另一个类从RabbitMq中侦听一些队列。 I want to write something like: 我想写一些类似的东西:

class MessageListener<T> where T : BaseDto {
        public void GetMessage<T>(Func ... )

        MessageListener<T>(string queueToListen)
        {
        }
}

The idea behind this code is that I want to use it as: 这段代码背后的想法是我想用它作为:

BillingService bs = new BillingService();
var listener = new MessageListener<BillingOperationRequestDto>();

listener.GetMessage<BillingOperationRequestDto>(bs.CheckBillingStatus);

I want to specifiy not only the data expected from queue, but also which method to invoke on this data. 我不仅要指定队列中预期的数据,还要指定调用此数据的方法。 Is it correct approach? 这是正确的方法吗? I thought about getting only one message from queue and than send data to another class, but didn't find an apporach to do it, so decided to run GetMessage in loop and specify what action should be performed when message appears. 我想从队列中只获取一条消息而不是将数据发送到另一个类,但没有找到一个apporach来执行它,因此决定在循环中运行GetMessage并指定当消息出现时应该执行的操作。

Update #1.1: Is there a way to send a delegate to 更新#1.1:有没有办法发送代表

listener.GetMessage<BillingOperationRequestDto>(bs.CheckBillingStatus);

if my methods in BillingService class will have different method signatures? 如果我在BillingService类中的方法会有不同的方法签名? For example, 例如,

public BillingStatusResult CheckBillingStatus(BillingOperationRequestDto dto)
{
}
public AnotherReturnValue AnotherOperationOnBilling(BillingOperationRequestDto dto, string requestedIp, TimeSpan period)
{
}

As @juharr already mentioned, you can use generic delegates (which has type of Action<T> or Func<T, TResult> if you need to retrieve result from a delegate). 正如@juharr已经提到的,你可以使用泛型委托(如果你需要从委托中检索结果,那么它具有Action<T>Func<T, TResult> )。

More information you can find in this question or documentation 您可以在问题或文档中找到更多信息

class MessageListener<T> where T : BaseDto {
    public void GetMessage<T>(Action<T> action)
    {
    }

    MessageListener<T>(string queueToListen)
    {
    }
}

A Func<T, TResult> is a delegate that returns a result. Func<T, TResult>是一个返回结果的委托。 You'll want to use an Action<T> , which does not return a result. 您将要使用Action<T> ,它不会返回结果。 The generic type parameters of your Action<T> must match the signature of the method you'll be passing. Action<T>的泛型类型参数必须与您要传递的方法的签名相匹配。

Oftentimes when consuming messages coming off of a message queue, you'll have a listener class that wraps the client for that message queue and you'll handle a MessageReceived event within your listener (I'm speaking in general terms - I've not worked specifically with RabbitMQ). 通常在消费来自消息队列的消息时,您将拥有一个侦听器类来包装该消息队列的客户端,并且您将在侦听器中处理MessageReceived事件(我说的是一般性的 - 我没有专门与RabbitMQ合作)。 So your listener might look something like this (pseudocode): 所以你的听众可能看起来像这样(伪代码):

class MessageListener<T> where T : BaseDto {
    var _client = new QueueClient();

    MessageListener<T>(string queueToListen, Action<T> onMessageReceived)
    {
        _client = new QueueClient("<your_connection_string>", queueToListen);
        _client.MessageReceived += onMessageReceived;
    }
}

Usage would then be something like this: 用法将是这样的:

BillingService bs = new BillingService();
var listener = new MessageListener<BillingOperationRequestDto>("myQueue", bs.CheckBillingStatus);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM