mdevilliers / SignalR.RabbitMq

MessageBus implementation using RabbitMq as the backing store.
MIT License
89 stars 40 forks source link

Provide overloads that take a preconstructed IBus #7

Closed bytenik closed 11 years ago

bytenik commented 11 years ago

We use EasyNetQ in our app already, and I don't want to have a second instance in your library. Can you provide overloads that will take a pre-existing IBus instance and use that instead of going back to the RabbitHutch to create a new one?

mdevilliers commented 11 years ago

Hey,

Rather than push an IBus all the way through the code how would you feel about being provided with an extension point? There are already a few overloads and I am reticent about adding another (but not totally against it by any means ... I was just wanting to explore other options).

If we were to provide a base class that you could sub class -

    public class RabbitConnectionBase : IDisposable
    {
        // implement this method in your class
        public void virtual Send(RabbitMqMessageWrapper message)
        {
             throw new NotImplementedException();
        }

        // when your class recieved a message pass it to this callback
        public void OnRecieved(RabbitMqMessageWrapper message)
        {
            // pass the message on to the message bus
        }
    }

You would then be able to wire up your implementation using your own class that extends the above and register it with the IDependancyResolver when you set up the SignalR.RabbitMq message bus...

var myRabbitConnectionClass = new Lazy<MyRabbitConnectionClass>(() => new MyRabbitConnectionClass ());
GlobalHost.DependencyResolver.Register(typeof(RabbitConnectionBase), () => bus.Value);

GlobalHost.DependencyResolver.UseRabbitMq();

or something like that?

I think it would allow everyone to tweak their connections as they wish, implement it with what ever library they want whilst still keeping a simple easy to use default.

What do you think?

bytenik commented 11 years ago

That makes a lot of sense to me.

It would be good if you also included a prebuilt class to use that takes an IBus constructor argument; perhaps you could then use this class throughout your code, too. Since I use Autofac for DI, my IBus is available to the dependency injector anyway. Merely registering a class like that with Autofac would be enough for it to know how to produce it.

mdevilliers commented 11 years ago

Hey,

I've updated the Nuget package of the project and added a way of supplying your own class that handles the connections/interactions with RabbitMQ.

Essentially you extend the class RabbitConnectionBase.

There are 2 methods you can override

        public virtual void Send(RabbitMqMessageWrapper message)
        {
         //handle the sending of messages to your instance of Rabbit
        }

        public virtual void StartListening()
        {
          // handle the connection to rabbit
        }

When you receive a message call OnMessage( myMessage ) If you get disconnected call OnDisconnection() and when you reconnect call OnReconnection(). The implementations are provided by the base class.

The class EasyNetQRabbitConnection gives an implementation using the EasyNeyQ (but the IAdvancedBus rather than the IBus)

To wire up your class use GlobalHost.DependencyResolver.UseRabbitMqAdvanced(...);

Would you have a chance to look at it and see if it meets your needs?

bytenik commented 11 years ago

I'm trying to use the existing EasyNetQRabbitConnection with my IAdvancedBus instance, but I'm not seeing an easy way to create one to use. Am I missing something obvious?

mdevilliers commented 11 years ago

There isn't a way to do this.

I was thinking you would be able to write your own implementation that extends RabbitConnectionBase then pass that to the configuration object e.g.

public class MyConnection : RabbitConnectionBase
{

   public MyConnection( IAdvancedBus bus){
     //code to configure
   }

   /// implement as above
}

//where you configure signalr
var connection = new MyConnection(myBus);
var configuration = new RabbitMqScaleoutConfiguration(connection);
GlobalHost.DependencyResolver.UseRabbitMq(configuration); ;

If that makes sense?

bytenik commented 11 years ago

This doesn't make sense; since you have to implement your own version of this class internally anyway, why make the users implement it also? The most common implementation is going to be just having an existing bus and providing it to you.

mdevilliers commented 11 years ago

Maybe you are right - I'm not too sure what the most common implementation is going to be. Most people who have expressed a view want to have the control over the connection (as I think you do).

The libraries bus implementation is how I have implemented the connection for people who don't have that requirement. I implemented it with EasyNetQ mainly because it has all of reconnection logic built in.

At my work we do need the control and don't use EasyNetQ so if we wanted to use this library we would supply our own connection implemented using the lower level RabbitMQ.Client classes.

If its ok with you I might go off and read the EasyNetQ source and see how it manufactures the IBus -> maybe it will give out the same instance and its a moot point.

bytenik commented 11 years ago

Sure; however, in the meantime if you can make a constructor for your already implemented code take an IBus/IAdvancedBus that would be great so that I don't have to copy and paste your code.

On Mon, Apr 29, 2013 at 4:59 PM, mdevilliers notifications@github.comwrote:

Maybe you are right - I'm not too sure what the most common implementation is going to be. Most people who have expressed a view want to have the control over the connection (as I think you do).

The libraries bus implementation is how I have implemented the connection for people who don't have that requirement. I implemented it with EasyNetQ mainly because it has all of reconnection logic built in.

At my work we do need the control and don't use EasyNetQ so if we wanted to use this library we would supply our own connection implemented using the lower level RabbitMQ.Client classes.

If its ok with you I might go off and read the EasyNetQ source and see how it manufactures the IBus -> maybe it will give out the same instance and its a moot point.

— Reply to this email directly or view it on GitHubhttps://github.com/mdevilliers/SignalR.RabbitMq/issues/7#issuecomment-17193989 .

mdevilliers commented 11 years ago

Cool - if you have a look at commit you should see your overload. Any feedback would be great?

I've got a bit more testing to do before I push the nuget package.