tags:

views:

56

answers:

1

Hello. I want to have several buses in one process. I googled about this and found that it is possible only if having several AppDomains. But I cannot make it work.

Here is my code sample (I do everything in one class library):

using System;
using System.Diagnostics;
using System.Reflection;
using MyMessages;
using NServiceBus;
using NServiceBus.Config;
using NServiceBus.Config.ConfigurationSource;

namespace Subscriber1
{
public class Sender
{
    public static void Main()
    {
        var domain = AppDomain.CreateDomain("someDomain", AppDomain.CurrentDomain.Evidence);
        domain.Load(Assembly.GetExecutingAssembly().GetName());
        domain.CreateInstance(Assembly.GetExecutingAssembly().FullName, typeof (PluginBusCreator).FullName);
        //here I have some code to send messages to "PluginQueue".
    }
}

public class PluginBusCreator
{
    public PluginBusCreator()
    {
        var Bus = Configure.With(
            Assembly.Load("NServiceBus"), Assembly.Load("NServiceBus.Core"),
            Assembly.LoadFrom("NServiceBus.Host.exe"), Assembly.GetCallingAssembly())
            .CustomConfigurationSource(new PluginConfigurationSource())
            .SpringFrameworkBuilder()
            .XmlSerializer().MsmqTransport()
            .UnicastBus().LoadMessageHandlers<First<SomeHandler>>().CreateBus().Start();
    }

    protected IBus Bus { get; set; }
}

class PluginConfigurationSource : IConfigurationSource
{
    public T GetConfiguration<T>() where T : class
    {
        {
            if (typeof (T) == typeof (MsmqTransportConfig))
                return new MsmqTransportConfig
                        {
                            ErrorQueue = "error",
                            InputQueue = "PluginQueue",
                            MaxRetries = 1,
                            NumberOfWorkerThreads = 1
                        } as T;
            return null;
        }
    }
}

public class SomeHandler : IHandleMessages<EventMessage1>
{
    public void Handle(EventMessage1 message)
    {
        Debugger.Break();
    }
}

}

And I don't get handler invoked. If you have any ideas, please help. I'm fighting this problem a lot of time. Also if full code need to be published, please tell.

I need several buses to solve the following problem :

I have my target application, and several plugins with it. We decided to make our plugins according to service bus pattern.

Each plugin can have several profiles.

So, target application(it is web app.) is publishing message, that something has changed in it. Each plugin which is subscribed to this message, need to do some action for each profile. But plugin knows nothing about its profiles (customers are writing plugins). Plugin should only have profile injected in it, when message handling started.

We decided to have some RecepientList (pattern is described in "Enterprise Integration Patterns"), which knows about plugin profiles, iterates through them and re-send messages with profiles injected.(So if plugin has several profiles, several messages will be sent to it).

But I don't want to have each plugin invoked in a new process. Perfectly I want to dynamically configure buses for each plugin during start. All in one process. But it seems I need to do it in separate AppDomains. So I have a problem described above:-).

A: 

Sergey,

I'm unclear as to why each plugin needs to have its own bus. Could they all not sit on the same bus? Each plugin developer would write their message handlers as before, and the subscriptions would happen automatically by the bus.

Then, also, you wouldn't need to specify to load each of the NServiceBus DLLs.

BTW, loading an assembly by name tends to cause problems - try using this to specify assemblies:

typeof(IMessage).Assembly, typeof(MsmqTransportConfig).Assembly, typeof(IConfigureThisEndpoint).Assembly

Udi Dahan
Thaks for your answer, Udi!Let me explain a bit deeper : i.e. I have two plugins listening to Entity Updated message. Each plugin has several profiles. When target application sends Entity Updated message to plugins, I want the following to happen1.) Plugin 1 receives two messages. Each message has the similar context, but different profiles injected.2.) Plugin 2 -- the same.And this functionality of injection profile data in message is a duty of my Recepient List.I don't see how this can be implemented if there will be only one bus for all plugins.
Sergey