Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass in a generic list to a method in c#

Tags:

c#

generics

I have a Mediator class with a register pipeline method that takes a message type, a pipeline filter type, and a message handler type.

internal static void RegisterPipeLine<T1, T2, T3>()
      where T1 : IMessage
      where T2 : BaseFilter
      where T3 : IMessageHandler
  {
      var pipeLine = new PipeLine()
      {
          Filters = [typeof(T2)],
          MessageHandler = typeof(T3)
      };
      pipeLines[typeof(T1)] = pipeLine;
  }

Which I call like so

  Mediator.RegisterPipeLine<Message1, LogFilter, MessageHandler1>();

This works fine, except I want to have multiple pipeline filters. So far I've overloaded the RegisterPipeLine method like this

 internal static void RegisterPipeLine<T1, T2, T3, T4>()
        where T1 : IMessage
        where T2 : BaseFilter
        where T3 : BaseFilter
        where T4 : IMessageHandler
     {
         var pipeLine = new PipeLine()
         {
             Filters = [typeof(T2), typeof(T3)],
             MessageHandler = typeof(T4)
         };
         pipeLines[typeof(T1)] = pipeLine;
     }

Which I call like

 Mediator.RegisterPipeLine<Message2, LogFilter, ValidFilter, MessageHandler2>();

But I don't want to have to create a specific overload for every number of filters I want in the pipeline.

Is there a way to do this nicer?

like image 706
David Kethel Avatar asked Nov 22 '25 13:11

David Kethel


2 Answers

You might use something like the builder pattern:

public class PipelineBuilder<TMessage,TMessageHandler>() where TMessage: IMessage, TMessageHandler : IMessageHandler
{
   private List<Type> filters = new List<Type>();

   public PipeLineBuilder<TMessage,TMessageHandler> WithFilter<TFilter>() where TFilter : BaseFilter
   {
      filters.Add(typeof(TFilter));
      return this;
   }

   public void Register()
   {
      var pipeLine = new PipeLine()
      {
          Filters = filters,
          MessageHandler = typeof(TMessageHandler)
      };
      pipeLines[typeof(TMessage)] = pipeLine;
   }
}

Usage is

 new PipelineBuilder<Message2, MessageHandler2>()
       .WithFilter<LogFilter>()
       .WithFilter<ValidFilter>()
       .Register();
like image 84
SomeBody Avatar answered Nov 25 '25 04:11

SomeBody


Why don't you prefer to use params keyword? If you do so, we can handle multiple filters without creating separate overloads for each number of filters.

internal static void RegisterPipeLine<TMessage, THandler>(params Type[] filterTypes)
    where TMessage : IMessage
    where THandler : IMessageHandler
{
    var pipeLine = new PipeLine()
    {
        Filters = filterTypes,
        MessageHandler = typeof(THandler)
    };
    pipeLines[typeof(TMessage)] = pipeLine;
}

We can call as such.

Mediator.RegisterPipeLine<Message1, MessageHandler1>(typeof(LogFilter), typeof(ValidFilter));

By doing so, we can call with any number of filter types.

like image 40
snr Avatar answered Nov 25 '25 02:11

snr



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!