NHibernate Multiple Event Listeners - c#

Is it possible to register multiple event listeners?
We currently register event listeners using .ExposeConfiguration(AddSoftDelete) in which AddSoftDelete is a class registering the listener;
private static void AddSoftDelete(Configuration config)
{
config.SetListener(ListenerType.Delete, new SoftDeleteListener());
}
We have found that we cannot register multiple event listeners of the same type, i.e. we cannot register more than one listener for "ListenerType.Delete".
Is it possible to register new listeners without overriding any existing ones?
Solved...
Have managed to register multiple listeners using the following code;
config.EventListeners.PreUpdateEventListeners = new IPreUpdateEventListener[]
{
new Listener1(),
new Listener2()
};
Repeat for each ListenerType.

The listeners are not actually listeners, they are implementors. There could only be one implementation of an "event".
You could implement a listener where you could plug in several implementations. For instance an implementation for different entity types. You could pass the "event" to each implementation until one of them handles it (eg. when the ISoftDeletable interface is implemented, the SoftDeleteImplementor is handling it). You need to care about competing implementors (more the one could be handling it, the order matters in which you call them).

Why is there a need to register more than one ListenerType.Delete?
If you've got multiple event listeners on one type, there will be some performance issues on your application. If you want to handle different entities with this listener, so do it in your SoftDeleteListener class.

I do something similar in my code. There should be an AppendListeners(ListenerType type, object[] listeners) method on the NHibernate.Cfg.Configuration object.
There's also a SetListeners method which I assume replaces the listener list instead of adding on to it.

Related

Forwarding events to selected instance

Is there a good strategy to exchange the receiver of multiple events (let's say an object instance A) during runtime to another instance B (or multiple instances)? For example think of a menu bar with a bunch of operations that can be performed on the currently selected of multiple objects.
Now one option would be to connect all object's handlers to the click events and let the handlers filter out the relevant calls (by checking if the current instance is selected) or registering/unregistering the events on selection.
Another one would be to register the events to an object functioning as proxy like this (rough code):
class ClickEventProxy
{
private static ClickEventProxy selectedInstance; // <-- changend on selection
public event EventHandler SomeEventToForward;
public static void RaiseSomeEventToForward(object sender, EventArgs e)
{
if (selectedInstance.ClickedAddNewFrame != null)
selectedInstance.ClickedAddNewFrame(sender, e);
}
...
}
The sender-site would look like SomeSource.Click += ClickEventProxy.RaiseSomeEventToForward; and all receivers would subscribe to their instance of the proxy.
However handling the instances (e.g. by a global <object, proxy instance> dictionary) is a bit unconvenient and the whole thing looks a bit clumsy. So my question: Is there a more programmatic way to do so? Or is it itself bad practice proxying events by introducing another step and one should rather remove and readd the handlers? (Maybe this could be made better by using custom events and altering the invocation list...)

Design decision - Factory vs Observer Pattern

I have the following scenario:
I have a QueueReader class that will be reading messages from a queue. I also have some Senders like EmailSender and SMSSender, that will send these messages to clients using Email or SMS respectively. In the future more Senders can be added.
I can think of two ways of doing this and I am not sure which would be more beneficial.
Factory Pattern:
I can have a SenderManager that will use a SenderFactory to create the appropriate sender and then call its Send() method.
So the QueueReader upon reading a message will call the SenderManager's Send() which will do the following:
IMySender sender = SenderFactory.CreateSender()
sender.Send()
//I have the information to create the proper Dispatcher in the
//factory based upon the message but I have omitted it for brevity.
So, now if I have to add a new sender, I won't have to change the QueueReader or the SenderManager. I will just add the new Sender and modify the SenderFactory.
Observer Pattern
In contrast to the above, I can have the QueueReader class implement an Event for NewMessage. Then have all my Senders subscribe to this event. The Sender will have access to the information that was in the Factory above to know if the message is for them.
The benefit of this would be any new Sender will simply have to subscribe to the event.
Now that I have written all of this down, I think the Observer Pattern is the cleaner approach...
However, if anyone has any insight or suggestion, please do share.
Thanks!
I would use an hybrid approach:
SenderManager (The observer) would listen to the incoming messages and pick the right sender (or ask the SenderFactory to create one if needed). This has 2 benefits:
First, you have control over which sender you pick (You don't need to expose the SenderManager class) avoiding attack of type ManInTheMiddle. This is particularly important if you are going to expose an API for other developers to implement their own senders.
Second, you can implement a sort of Garbage Collector and dispose of the sender that are no longer needed, instead of having multiple senders that are instantiated and monitoring your stream for nothing.
You will need some kind of registration function to register the senders against the SenderManger.
If you use an ObserverPattern, don't forget to implement a default sender (can be a log system) in order to handle the unwanted messages.
Factory pattern will be fine if you want to create instance based on certain criteria.
If you are sure that you will use either SMS or Email sender then you can consider using Dependency Injection as well and let IMySender be resolved on runtime using any DI container. For example, StructureMap.
I am not sure about observer pattern, seems to be a bit complex.

NServiceBus custom message handler type

Is there a way in NServiceBus to replace the IHandleMessages<> handler with my own version of this interface that isnt strongly tied to NServiceBus?
I have found ways of replacing the event/command marker interfaces (Via NServiceBus 3 Unobtrusive syntax) but no way of doing the same for the actual handler. I am trying to do this to remove the coupling between my handlers and NServiceBus.
I found it possible with little code required:
1) Create a generic class implementing IHandleMessages<TMessage> and implement the Handle method making it find or create the correct instance of your custom handler (from DI container, static registry etc.). In this example assume that you've got MyCustomHandler class with void HandleMessageMyWay(object message) method accepting any message type:
public class MessageHandlerAdapter<TMessage>
: IHandleMessages<TMessage>
{
public void Handle(TMessage message)
{
new MyCustomHandler().HandleMessageMyWay(message);
}
}
It's an open generic, so NServiceBus won't discover it as a valid handler, because you need a closed generic (with TMessage being a concrete type like MyMessage1) to be seen by NServiceBus as a handler for the concrete type.
2) Implement ISpecifyMessageHandlerOrdering. In it's SpecifyOrder method make (at runtime) a closed generic adapter type for each message type which you want to support:
public class MessageHandlerAdapterLister : ISpecifyMessageHandlerOrdering
{
public void SpecifyOrder(Order order)
{
//You would normally iterate through your message types (over DI registry or some other registry of messages):
var adapterType1 = typeof(MessageHandlerAdapter<>).MakeGenericType(typeof(MyMessage1));
var adapterType2 = typeof(MessageHandlerAdapter<>).MakeGenericType(typeof(MyMessage2));
order.Specify(new[] { adapterType1, adapterType2 });
}
}
ISpecifyMessageHandlerOrdering instances are automatically discovered by NServiceBus. These are normally used to specify order for handler types which are discovered by NServiceBus. Apparently when you specify types which have not been discovered (like our closed generic adapter types made at runtime), it will simply add them to the registry.
That's all you need. NServiceBus will route MyMessage1 and MyMessage2 through the open generic IHandleMessages<TMessage> which then delegates handling to your custom class.
The reason for the NServiceBus 3.0 Unobtrusive Mode (see Andreas Ohlund's article on this) is that event definitions shared between multiple services can get into trouble if different endpoints are running different versions of NServiceBus, because the version on NServiceBus.dll that you are taking a dependency on will not match.
This argument does not hold water with the message handlers (the classes implementing IHandleMessages) themselves. There's no sharing of handlers. The message handler is, by definition, coupled to NServiceBus.
This seems to not be possible with NServiceBus.
The way i made this as unobtrusive as possible was to create a NServiceBus proxy to forward messages to my own bus, this kept the NServiceBus references out of most of my projects.

Observer Pattern or just create event handling?

I want to create a "modules" layout in my web application so I can easily add more modules of the same type, for example:
As an example, my WebApp handles subscriptions and email campaigns, and I want to create an interface to allow easily coupling multiple API's, MailChimp, CampaignMonitor, iContact, etc...
so I will create an IMailingService interface where I set up the ground rules and all modules will implement it like
public class CampaignMonitorService : IMailingService
So far so good...
How about fire the interface method upon an action on my webapp?
Should I implement the Observer Design Pattern, should I simple create event handlers, or any other hook?
for example, upon a user subscription I would like to fire the AddSubscriber method on the interface
AddSubscriber(string email, string[] args);
some thing as creating a list, unsubscribing, etc, etc...
What would be the best approach to handle such scenario?
Event handlers are how the Observer pattern is normally implemented in .NET. The pattern is a first class citizen of the .NET world, very much like how the Iterator pattern is built in (with foreach and yield return).
If you do want to use the pattern without events/event handlers, you can use the new IObserver<T> and IObservable<T> (introduced in .NET 4.0).

Auto wire event handlers with StructureMap?

Say I have an event defined in an interface.
I then have many classes that implement that interface.
The creation of these classes is managed by StructureMap.
Now say I have one delegate that I want to use as the event handler for ALL of these newly created instances.
Is there a way to tell StructureMap to append an event handler to objects it creates?
(NOTE: My current solution is to create a Notifier class and pass that in through the constructor, which gets the job done, but I'm curious if I can eliminate the middleman.)
If you take a look at http://structuremap.sourceforge.net/Interception.htm there is an explanation to EnrichWith()
Add the the event handler and return the original object and you should have what you want.

Categories