1

I'm building a program that will be processing messages from various topics. Since the data on each topic is different, I need dedicated classes that consumes data from any given topic. I want to do so using a base class that handles the communicates with the messaging system, and derived classes that implement the handling of the message:

public abstract class MessageConsumer<T>
{
   public void Start(){/*omitted*/}
   /* Other abstract properties and methods here to support template pattern*/       
}

The Start method will tell the MessageConsumer to start pulling in new message. Examples of derived classes are:

public class CreatedMessageConsumer : MessageConsumer<CreatedMessage>
{
   /*Implementation omitted*/
}
public class DeletedMessageConsumer : MessageConsumer<DeletedMessage>{}

In the code snippet above, I omitted the required constructor arguments, but it's easy to imagine how a DiContainer can be useful here. I use Autofac. The registration of CreatedMessageConsumer and DeletedMessageConsumer using Autofac works well.

My problem is how to resolve all classes that derives from MessageConsumer<>. This SO post discusses how to resolve a given derived type, but I want to resolve all types that derive from MessageConsumer. Subsequently I want to call the Start method on all of them, e.g. something like

foreach(var consumer in container.Resolve<IEnumerable<MessageConsumer<??>>())
{
  consumer.Start();
}

However, because I cannot provide the generic argument, it will not compile. Any idea how to do this? I'm using Autofac 4.2.1.

SimonAx
  • 1,176
  • 1
  • 8
  • 32

1 Answers1

3

If you do not care about the generic argument, (which you don't otherwise you would have specified a generic argument in your last code block), then:

  • Define an interface (with method Start)
  • Implement that on your type(s)
  • Add it to the As chain where you define your Autofac registrations
  • Resolve the new interface

Updated code:

public interface IStartable {
    void Start();
}

public abstract class MessageConsumer<T> : IStartable
{
   public void Start(){/*omitted*/}
   /* Other abstract properties and methods here to support template pattern*/       
}

Caling code:

foreach(var consumer in container.Resolve<IEnumerable<IStartable>>())
{
  consumer.Start();
}
Igor
  • 60,821
  • 10
  • 100
  • 175