Using IConsumer without parameterless constructor

2,731 views
Skip to first unread message

Annie Ju

unread,
Jul 1, 2015, 7:05:36 PM7/1/15
to masstrans...@googlegroups.com
Hi,

I'm trying to receive messages on a queue, and have a consumer handle the incoming messages.  
I have a Consumer class that doesn't have a default constructor, and it instantiates the MassTransit class that initializes the bus, and sets up the receive, etc.

MessageBus class:

            _bus = Bus.Factory.CreateUsingRabbitMq(x =>
            {
                IRabbitMqHost rabbitMQHost = x.Host(_hostAddress, h =>
                {
                    h.Username("x");
                    h.Password("x");
                });

                    x.ReceiveEndpoint(rabbitMQHost, consumeQueue,
                            e => { e.Consumer<MyAppClass>(); });


MyAppClass:

    public class MyAppClass: SomeOtherBaseClass, IConsumer<MyMessage>
    {
        MessageBus messageBus;

        public MyAppClass(<some parameters>)  { ...}

        public Activate() { messageBus = new MessageBus(); }

        public async Task Consume(ConsumeContext<MyMessage> context)
        {
            // call some class methods passing in the message
        }


When I compile, I get this error.  Is there another way to do this without having a parameterless constructor for MyAppClass?  I could use a message handler, but would rather use a Consumer as it's more flexible.
And why is it designed to only allow a parameterless constructor?

Error 9 'MyAppClass' must be a non-abstract type with a public parameterless constructor in order to use it as parameter 'TConsumer' in the generic type or method 'MassTransit.ConsumerExtensions.Consumer<TConsumer>(MassTransit.IReceiveEndpointConfigurator)'


Thanks,
Annie

Travis Smith

unread,
Jul 1, 2015, 7:15:04 PM7/1/15
to masstrans...@googlegroups.com
Annie, 

How would you like an instance of your consumer created? You can call e.Consumer(() => new MyAppClass(....)); instead. Or you can use a container integration. 

--
You received this message because you are subscribed to the Google Groups "masstransit-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to masstransit-dis...@googlegroups.com.
To post to this group, send email to masstrans...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/masstransit-discuss/a62bce2b-2ac2-4fe3-a939-5222f7650277%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
--
-Travis

Annie Ju

unread,
Jul 1, 2015, 7:34:29 PM7/1/15
to masstrans...@googlegroups.com
Hi Travis,

I create the consumer MyAppClass outside using Autofac as part of other class creations.

I'm wondering if I should separate out the consumer class from MyAppClass, and have the consumer Consume() call the MyAppClass() methods with the incoming message.

Thanks,
Annie
To unsubscribe from this group and stop receiving emails from it, send an email to masstransit-discuss+unsub...@googlegroups.com.
--
-Travis

Dru Sellers

unread,
Jul 1, 2015, 11:35:22 PM7/1/15
to masstrans...@googlegroups.com
"And why is it designed to only allow a parameterless constructor?"

Hi Annie,

Once you start using ctor's (ctor = constructor) with parameters, we (masstransit) no longer really know how to call your ctor. Hopefully, that makes sense, because we just don't know how to supply your parameters. So, if all you register is a type with no factory function, our only real option is a default ctor, because we can just say `new TConsmer()`

But, you DO want to supply parameters so, that leaves you with two options. One, you can register your consumer in AutoFac (which can create just about anything) and simple delegate the creation to the container. (see http://docs.masstransit-project.com/en/latest/configuration/containers.html) or you can use the syntax like

s.Consumer(()=> _container.Resolve<MyAppClass>(); );

Then you can build the class however you want, including
s.Consumer(()=> new MyAppClass(param1, param2) );
So, if you are already using AutoFac then you should be good to go. We have many applications using AutoFac (and IoC) in general - with consumers having a whole variety of ctor args.

I hope this helps.

To unsubscribe from this group and stop receiving emails from it, send an email to masstransit-dis...@googlegroups.com.
--
-Travis

--
You received this message because you are subscribed to the Google Groups "masstransit-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to masstransit-dis...@googlegroups.com.

To post to this group, send email to masstrans...@googlegroups.com.

Chris Patterson

unread,
Jul 2, 2015, 2:03:04 PM7/2/15
to masstrans...@googlegroups.com
And you can also just use:

    s.Consumer(new AutofacConsumerFactory<TConsumer>(yourLifetimeScope));

The AutofacConsumerFactory is in the MassTransit.Autofac NuGet package.


Annie Ju

unread,
Jul 2, 2015, 2:03:30 PM7/2/15
to masstrans...@googlegroups.com
Hi Dru,

Thanks, this is very helpful. 

For now I got it to work by having a separate consumer class ConsumerClass  from MyAppClass and construct that using the method you and Travis stated, with parameters since I needed that.
MyAppClass calls into the MassTransit init code which creates a ConsumerClass that has a delegate to one of MyAppClass's functions.  
This is not the most versatile, but it works.

Later I will try out the container solution, though I may want to decouple the MassTransit from the creation of the many classes I have via Autofac.  Also for design reasons I may not want to make MyAppClass a IConsumer, and I don't want to create MyAppClass via any other way than Autofac.  Still need to think about that.

Thanks,
Annie
To unsubscribe from this group and stop receiving emails from it, send an email to masstransit-discuss+unsub...@googlegroups.com.
--
-Travis

--
You received this message because you are subscribed to the Google Groups "masstransit-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to masstransit-discuss+unsub...@googlegroups.com.

To post to this group, send email to masstrans...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages