简体   繁体   中英

Resolve all derived classes of generic abstract class using Autofac

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, eg 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.

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();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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