I've been studying on domain driven design in conjunction with domain events. I really like the separations of concerns those events provide. I ran into an issue with the order of persisting a domain object and raising domain events. I would like to raise events in the domain objects, yet I want them to be persistence ignorant.
I've created a basic ShoppingCartService, with this Checkout method:
public void Checkout(IEnumerable<ShoppingCartItem> cart, Customer customer)
{
var order = new Order(cart, customer);
_orderRepositorty.Add(order);
_unitOfWork.Commit();
}
In this example, the constructor of Order would raise an OrderCreated event which can be handled by certain handlers. However, I don't want those events to be raised when the entity is not yet persisted or when persisting somehow fails.
To solve this issue I have figured several solutions:
1. Raise events in the service:
Instead of raising the event in the domain object, I could raise events in the service. In this case, the Checkout method would raise the OrderCreated event. One of the downsides of this approach is that by at looking the Order domain object, it isn't clear which events are raised by what methods. Also, a developer has to remember to raise the event when an order is created elsewhere. It doesn't feel right.
2. Queue domain events
Another option is to queue domain events and raise them when persisting succeeded. This could be achieved by a using statement for example:
using (DomainEvents.QueueEvents<OrderCreated>())
{
var order = new Order(cart, customer);
_orderRepositorty.Add(order);
_unitOfWork.Commit();
}
The QueueEvents<T> method would set a boolean to true and the DomainEvents.Raise<T> method would queue the event rather than executing it directly. In the dispose callback of QueueEvent<T>, the queued events are executed which makes sure that the persisting already happened. This seems rather tricky and it required the service to know which event is being raised in the domain object. In the example I provided it also only supports one type of event to be raised, however, this could be worked around.
3. Persist in domain event
I could persist the object using a domain event. This seems okay, except for the fact that the event handler persisting the object should execute first, however I read somewhere that domain events should not rely on a specific order of execution. Perhaps that is not that important and domain events could somehow know in which order the handlers should execute. For example: suppose I have an interface defining a domain event handler, an implementation would look like this:
public class NotifyCustomer : IDomainEventHandler<OrderCreated>
{
public void Handle(OrderCreated args)
{
// ...
}
}
When I want to handle persisting in using an event handler too, I would create another handler, deriving from the same interface:
public class PersistOrder : IDomainEventHandler<OrderCreated>
{
public void Handle(OrderCreated args)
{
// ...
}
}
}
Now NotifyCustomer behaviour depends on the order being saved in the database, so the PersistOrder event handler should execute first. Is it acceptable that these handlers introduce a property for example that indicates the order of their execution? A snap from the implementation of the DomainEvents.Raise<OrderCreated>() method:
foreach (var handler in Container.ResolveAll<IDomainEventHandler<OrderCreated>>().OrderBy(h => h.Order))
{
handler.Handle(args);
}
Now my question is, do I have any other options? Am I missing something? And what do you think of the solutions I proposed?
Either your (transactional) event handlers enlist in the (potentially distributed) transaction, or you publish/handle the events after the transaction committed. Your "QueueEvents" solution gets the basic idea right, but there are more elegant solutions, like publishing via the repository or the event store. For an example have a look at SimpleCQRS
You might also find these questions and answers useful:
CQRS: Storing events and publishing them - how do I do this in a safe way?
Event Aggregator Error Handling With Rollback
Update on point 3:
... however I read somewhere that domain events should not rely on a specific order of execution.
Regardless of your way of persisting, the order of events absolutely matters (within an aggregate).
Now NotifyCustomer behaviour depends on the order being saved in the database, so the PersistOrder event handler should execute first. Is it acceptable that these handlers introduce a property for example that indicates the order of their execution?
Persisting and handling events are separate concerns - don't persist using an event handler. First persist, then handle.
Disclaimer: I don't know what I am talking about. ⚠️
As an alternative to raising events in the ShoppingCartService you could raise events in the OrderRepository.
As an alternative to queuing domain events in the ShoppingCartService you could queue them in the Order aggregate by inheriting from a base class that provides a AddDomainEvent method.
public class Order : Aggregate
{
public Order(IEnumerable<ShoppingCartItem> cart, Customer customer)
{
AddDomainEvent(new OrderCreated(cart, customer))
}
}
public abstract class Aggregate
{
private List<IDomainEvent> _domainEvents = new List<IDomainEvent>();
public IReadOnlyCollection<IDomainEvent> DomainEvents => _domainEvents.AsReadOnly();
public void AddDomainEvent(IDomainEvent domainEvent)
{
_domainEvents.Add(domainEvent);
}
}
Related
I recently stumbled across the following in our application and I'm curious to know whether this is good or bad practice. What I see is events being subscribed to on different levels in the application, business logic and ultimately our framework.
We have functionality to authenticate and authorize users, which is orchestrated by an HttpModule which basically does the following (I only included the most relevant parts):
public class FooModule : IHttpModule
{
private IIdentityProvider _identityProvider;
public void Init(HttpApplication context)
{
_identityProvider = TypeFactory.Create<IIdentityProvider>("...type string from configuration...");
identityProvider.Init(context, ...);
context.PostAuthenticateRequest += OnAuthenticateRequest;
context.PostAuthenticateRequest += OnAuthenticateRequestLogging;
}
...
}
So far, so good: the HttpModule identifies the configured identity provider, initializes it and subscribes to some events. The event handlers are not in question here, so I omitted them.
Then, in the initialization of an arbitrary identity provider:
public class BarIdentityProvider : IIdentityProvider
{
public void Init(HttpApplication httpApplication, ...)
{
var authorizer = new BarAuthorizationProvider();
authorizer.Init(httpApplication, ...);
httpApplication.PostAuthenticateRequest += httpApplication_PostAuthenticateRequest;
httpApplication.AuthorizeRequest += httpApplication_AuthorizeRequest;
}
...
}
And in the AuthorizationRequestHandler the following happens:
public class BarAuthorizationProvider
{
public void Init(HttpApplication httpApplication, ...)
{
httpApplication.PostAuthorizeRequest += OnAuthorizeRequest;
}
...
}
As you can see, there are events being subscribed to in FooModule, BarIdentityProvider and BarAuthorizationProvider which, to me, comes across as event spaghetti. Also, when doing this:
var authorizer = new BarAuthorizationProvider();
authorizer.Init(httpApplication, ...);
I do not expect the authorizer to subscribe to various events and work 'magically'.
As a software developer I expect either:
one HttpModule which subscribes to the necessary events and requests the identity provider and authorization provider for identity and access information. Event handling is minimized in the providers.
multiple HttpModules (i.e. an authentication and an authorization module) which each subscribe to the necessary events. Event handling is minimized in the providers.
Am I correct or are there arguments against my expectation?
My first question would be, is it important that "Event handling is minimized in the providers"? I.e. what specific advantage is there to achieving that goal?
I also wonder what "event spaghetti" is supposed to mean. I mean, it clearly references the age-old concept of "spaghetti code", but that concept refers to code where the path of execution is convoluted, most often due to the use of unstructured flow-control (i.e. goto statements). I don't see how when discussing event handling, there's anything resembling spaghetti.
In other words, the phrase "event spaghetti" simply seems prejudicial here. I.e. the word "spaghetti" is just being thrown in because it's already understood as a pejorative. But lacking a clear objection to the implementation, the pejorative seems unjustified on its own, and the word "spaghetti" does not seem to offer a genuinely useful metaphor as it does in the context of "spaghetti code".
So, back to "minimizing event handling in the providers". Why should this be important? You write that "the event handlers are not in question here", but that seems to indicate that the handlers in the providers are appropriate. I.e. they do work that is relevant to the provider (likely only to the provider). So how else are they to do that work?
In my opinion (the fact that I wrote that suggests that your question might be considered off-topic, being "primarily opinion-based", but I think there's an objective way to look at this, even if that's simply my opinion :) ), one of the big advantages of the event-based programming model is reduced coupling. Assuming the work has to be done somewhere, the alternative to these provider objects subscribing to these events is for some other object to understand the needs of the provider object, and to fulfill that need on the provider objects' behalf.
But then you've just laden that other object with specific knowledge of the provider object. Which increases coupling between the types. Which is generally a bad thing.
If on the other hand, you feel that the event handlers in the providers can be moved to some other type without coupling the types more strongly, then that suggests the event handlers are indeed inappropriate in the providers. But in that case, the specific details of those event handlers most certainly is pertinent here, contrary to your assertion.
I.e. where the event handler goes depends a great deal on what it does. But since you don't seem concerned with the specific content of those handlers, that suggests they are right where they belong, and thus the subscription to events is not a problem at all.
I have a game with many classes that need to listen to events. But under certain circumstances, those classes are destroyed or disabled. When that happens, I need to remove their listening methods from the events manager delegate table.
I don't want to modify the EventsManager and I would like to each class that adds any events to it to know which events it added.
I'm currently using something like this do add and remove the events in each class:
void AddEventsListeners() {
EventsManager.AddListener<OnClickDown>(OnClickDownHandler);
EventsManager.AddListener<OnClickUp>(OnClickUpHandler);
EventsManager.AddListener<OnClick>(OnClickHandler);
}
void RemoveEventsListeners() {
EventsManager.RemoveListener<OnClickDown>(OnClickDownHandler);
EventsManager.RemoveListener<OnClickUp>(OnClickUpHandler);
EventsManager.RemoveListener<OnClick>(OnClickHandler);
}
Those OnClick are all derived from GameEventBase, and the OnClickHandler are methods declared as
void OnClickDown(OnClickHandler e) {}
to match the delegate that is used in the EventsManager, which is declared as
delegate void EventDelegate<T>(T e) where T : GameEventBase;
I want to be able to fill a special hash table named, say, events, that has keyvalue pairs like
<T, EventDelegate<T>> where T: GameEventBase
That is, I want to be able to do events.add(OnClick, OnClickHandler), where OnClickHandler is declared as
OnClickHandler(OnClick e) {}
And I want adding to fail if OnClickHandler where defined, for example, as
OnClickHandler(OtherGameEventBaseDerivedEvent e) {}
That requirement translates to me wanting type safety in that special dictionary.
One of my attempts involved not a dictionary, but a way to decide which method to call, between the AddListener and RemoveListener
I didn't like it because it introduces a parameter to the method and the code reads really weird with it. It does work, and does reduce the repetition, but is too ugly.
I create a AddOrRemoveAllListeners(AddOrRemove addOrRemove), which I populated with calls to AddOrRemoveListener for each event.
Now all I had to do is AddOrRemoveAllListeners(AddOrRemove.Remove) or AddOrRemoveAllListeners(AddOrRemove.Add), to add or remove my events.
enum AddOrRemove {
Remove,
Add
}
void AddOrRemoveListener<T>(EventsManager.EventDelegate<T> del, AddOrRemove addOrRemove)
where T : GameEventBase {
switch (addOrRemove) {
case AddOrRemove.Remove:
EvMan.RemoveListener<T>(del);
break;
case AddOrRemove.Add:
EvMan.AddListener<T>(del);
break;
}
}
Another attempt involved creating the type
class EventsDictionary<T> : Dictionary<T, EventsManager.EventDelegate<T>> where T : GameEventBase { }
And using it like this:
EventsDictionary<GameEventBase> events = new MyCustomDictionary<GameEventBase>();
void AddEventHandlerPairToEventsDictionary<T>(T e, EventsManager.EventDelegate<T> handler) where T : GameEventBase {
if (!events.ContainsKey(e)) {
events.Add(e, handler);
}
}
But the events.Add(e, handler) fails and forces me to declare the handler as
EventsManager.EventDelegate<GameEventBase>
instead of
EventsManager.EventDelegate<T>
If I do that, I could add keyvalue pairs that don't make sense in that events type, i.e., I lose the event handling type safety.
I want to have such a structure because I don't like all those repetitions. It would be really bad if someone forgot to remove an event in the RemoveEventsListeners().
Having such a dictionary, I could use a foreach loop to add/remove the handlers to the EventsManager, which would be really nice.
As for performance, this is for a game and it needs to have good performance. Those adding/removing of events can happen a lot (sometimes hundreds of times per frame) because a lot of objects are destroyed (can't leave null handlers in the EventsManager) or disabled (need to stop listening to everything until enabled again) all the time. This means reflection and lots of casting/boxing or anything that creates lots of garbage collected objects is out.
I'm, of course, open to suggestions as to other ways to approach this.
Thanks for your assistance!
I'm attaching the relevant parts of the EventsManager being used (The RemoveListener() is analogous to the AddListener). The GameEventBase is just an empty shell. It isn't a .NET event nor uses EventArgs.
public class EventsManager : ManagedBase {
public delegate void EventDelegate<T>(T e) where T : GameEventBase;
private delegate void EventDelegate(GameEventBase e);
private readonly Dictionary<Type, EventDelegate> delegates = new Dictionary<Type, EventDelegate>();
private readonly Dictionary<Delegate, EventDelegate> delegateLookup = new Dictionary<Delegate, EventDelegate>();
public void AddListener<T>(EventDelegate<T> del) where T : GameEventBase {
// Early-out if we've already registered this delegate
if (delegateLookup.ContainsKey(del)) {
return;
}
// Create a new non-generic delegate which calls our generic one.
// This is the delegate we actually invoke.
EventDelegate internalDelegate = (e) => del((T) e);
delegateLookup[del] = internalDelegate;
EventDelegate tempDel;
if (delegates.TryGetValue(typeof (T), out tempDel)) {
delegates[typeof (T)] = tempDel + internalDelegate;
}
else {
delegates[typeof (T)] = internalDelegate;
}
}
public void Raise(GameEventBase e) {
EventDelegate del;
if (delegates.TryGetValue(e.GetType(), out del)) {
del.Invoke(e);
}
}
}
Your problems seem to be solved if you use the EventAggregator pattern.
There is a short description of it by Martin Fowler
Some very good implementations of it already exist, for example in caliburn micro and
Microsoft Prism
The general idea is that you simplify event registration and deregistration and have a single source of events for many objects.
I never had performance issues with it. You simply put a _eventAggregator.Subscribe(this) when you want to start listening to events for an object and Unsubscribe if you want to stop. Whereever you want to fire an event, just publish it, EventAggregator does the routing.
This once again looks like an XY problem. OP seems to want to have a central place to handle event handlers, registration and disposal. The OP has gone down the route of trying to create a pattern that deal with this in a generic way, but has not looked into the state of the art regarding how this problem is typically solved. He has now come up against a problem in his design and is now asking for a solution to THAT problem, rather than the original problem of event handlers.
There are two good solutions to event handler registration lifecycle management that I know of in .net.
Weak Event Handler
You state that "It would be really bad if someone forgot to remove an event in the RemoveEventsListeners()." Yet do not actually mention WHY it is bad. Typically the only reason for this being bad is that the event handler will now keep an object in reference, that should be collected. With weak reference event handlers, the GC will still be able to collect your object, even when it subscribes to an object that is still alive.
Rx.Net
Rx.Net abstracts event registrations into IDisposables, which you can tie to the object's lifetime, assuming of course you want to control the lifetime of the registrations.
However I actually find the IObservable pattern much nicer to work with than event handler pattern, mostly because C# lacks first class support for event handlers (this is not the case with F#).
F#
Most of your problems will have stemmed from the short sighted design of events keyword handling in C# (specifically not making events a first class construct). F# however does support first class events, and thus should be able to support the pattern you are trying to construct.
Thus with this option you should scrap your code base and rewrite it in F#.
*EDIT added tongue in cheek option of rewriting in F#.
In the current version of the .NET framework, and under normal circumstances (i.e. without intentionally modifying the invocation list), are handlers for an event always invoked in the order in which they are registered? This would be consistent with the documented behavior of multicast delegates, with which events are implemented.
The accepted answer to this question says that invoking handlers in the order of their registration is an implementation detail that may change in some future version of the framework. I believe such a change by Microsoft is unlikely, therefore I am confining my question to the current version of the .NET framework. A comment on that same answer says that it is possible to register handlers such that they are not invoked in their registration order. If this is true then please demonstrate code that results in this out-of-order execution. Please do not include code which intentionally modifies the invocation list. What I am after here is whether or not I can depend on event handler invocation occurring in same order as registration in all current versions of the .NET framework.
You cannot be sure that an event will always be executed in a particular order. The definition of the event can always do whatever it wants, and the implementation of that event is not a part of the public API.
By default, events will use a single multicast delegate as the backing store for an event, but it is straightforward enough to use your own implementation instead. There is no way to tell (beyond looking at the source code) whether or not an event has a custom implementation or not.
One way of implementing an event to not have the described order would be:
public class Foo
{
private Stack<Action> stack = new Stack<Action>();
public event Action MyEvent
{
add
{
stack.Push(value);
}
remove { throw new NotImplementedException(); }
}
internal void OnMyEvent()
{
foreach (var action in stack)
action();
}
}
While most of the events in framework classes won't use a definition like this; most will use a multicast delegate, the only way to know is to look at the source code; you can't tell from, for example, looking at the documentation, whether an event is implemented like this or like:
public class Foo2
{
public event Action MyEvent;
}
That depends on how the event is implemented.
Ordinary (field-like) events store all of their handlers in a single multicast delegate.
Multicast delegates invoke their handlers in insertion order.
Other events are free to store their handlers in some other order. However, most non-standard implementations still use multicast delegates under the covers, stored in various ways (eg, EventHandlerList)
I have a "DataImporter" class [takes data from many sources and processes it] that I want to report back through an event when it "does something".
At the moment I have:
DataImporterStarted
DataImporterCompleted
DataImporterImportedData
DataImporterDeleted
But they all do the same thing...report back a simple string saying "Data Importer started at xx:xx" or "DataImporter Imported xxx Rows" etc.
Should I be keeping the events separate, or is there an accepted pattern/naming convention for this kind of "I'm doing something" event?
Thx
I was trying to avoid code like this:
var importer = new DataImporter();
importer.DataImporterStarted += new DataImporterStartedEventHandler(importer_DataImporterMessage);
importer.DataImported += new DataImportedEventHandler(importer_DataImporterMessage);
importer.DataImporterCompleted += new DataImporterCompletedEventHandler(importer_DataImporterMessage);
importer.RunDataImporter();
You could use something like create a DataImporterProgress event with a Action property like "Updated" or "Deleted" (an enumeration) and a Message string in it's eventArgs property.
As Adam already mentioned it would be easier to distinguish between these events for other classes, because every listener will only receive these kinds of events he liked. But if you think that everyone who subscribes to one of these events has to subscribe to all of them then it wouldn't make sense to make such a bunch of different events.
If you like to merge them, you are on your own. But maybe you can get some inspiration from the INotifyPropertyChanged and the ListChanged event, cause they are also some kind of aggregators for different kind of things that could happen. But this leads to the fact that the client has to inspect the incoming data from the event and make has maybe to throw away a lot of incoming events, cause they are out of interest.
I would keep them separate as suggested in other answers, too.
To avoid duplication of the handling code, you could setup your events with compatible signatures. That would allow you to register the same event handler function to all events.
I don't know if this make sense in your case. It depends on the context.
Events are rather heavy weight for this king of task, especially if the frequency is high.
Even though I'm not directly answering your question, I want to give you an alternative to the event based solution:
The solution involves event streams using Rx Framework, and exposing and IObservable(T) instead of an event.
The solution goes like this: the DataImporter class will expose an IObservable<string> property, which internally is implemented by a Subject<T> which will be used to raise events.
public class DataImporter {
private Subject<string> _StatusSubject = new Subject<string>();
public IObservable<string> Status { get { return _StatusSubject; }
...
}
How to raise an event in the stream:
void Foo()
{
// Do some work
_StatusSubject.OnNext("Some work has been done!")
}
How to subscribe to the event stream:
var importer = new DataImporter();
importer.Status.Subscribe(message => Console.WriteLine(message));
The advantage of using this approach is that you can use Linq operators to perform operations on the event stream in a very simple and straightforward manner.
Ex:
// Filter the stream of events, only to show short messages
importer.Status
.Where (message => message.Length < 100)
.Subscribe(message => Console.WriteLine(message));
// Add a timestamp to status messages
importer.Status
.TimeStamp()
.Subscribe(timestamped => Console.WriteLine(String.Format("Time:{0} Message: {1}", timestamped.Timestamp, timestamped.Value)));
// Buffer status messages each 5 secconds and return a list of messages
importer.Status
.BufferWithTime(Timespan.FromSeconds(5))
.Subscribe(list => Console.WriteLine(Strin.Join(new[] {Environment.Newline}, list));
And many more ...
I would say it is a nice thing to keep the events specialized, as long as they provide the according infrastructure (for example, where DataImporterCompleted's event args would offer nothing more, DataImporterImportedData's would provide the list of row that were just imported).
Other than that, if you want extremely simple functionality with just some status string, you can do something like:
public event Action<string> StatusUpdate;
You raise it with:
StatusUpdate("some status string");
Your handlers will look like:
void HandleStatusUpdate(string status)
Or you can use the standard .NET pattern:
class MyEventArgs: EventArgs {}
public event EventHandler<MyEventArgs> MyEvent;
And so on...
What purpose do protected or private (non-static) events in .NET really serve?
It seems like any private or protected event is more easily handled via a virtual method. I can (somewhat) see the need for this in static events, but not for normal events.
Have you had a use case before that clearly demonstrates a need or advantage for a non-static protected or private event?
Here's a slightly bizarre but real-world scenario I implemented once. You have machine-generated and user-generated halves of a partial class. The machine-generated half contains code which wishes to inform the user-generated half when some event occurs. But the user-generated half might not care to do anything, or it might care to do rather a lot. It seems rude of the machine-generated half to require that the user-generated half implement a particular method in order to handle a message they don't have any interest in listening to.
To solve this problem, the machine-generated half could fire on a private event. If the user-generated half cares, it can subscribe the event. If not, it can ignore it.
This scenario is now addressed more elegantly by partial methods in C# 3, but that was not an option back in the day.
Seems to me that a good example of where a private event is useful is in component/control building, often you may have a component that is a composite of 1 or more other components, private events that contained components can subscribe to is a handy and easy implementation of an observer pattern.
Edit:
Let me give an example...
Say you are writing a Grid type control, and inside of this control you would most likely have a bunch of contained classes that are created dynamically Rows, Cols, headers etc for example, say you want to notify these contained classes that something they care about has happend, say a Skinning change or something like that, something that you don't necesarrily want to expose as an event to the grid users, this is where private events are handy, simply have one or 2 handlers and as you create each instance of your row or col or whatever attach the handler, as otherwise you just have to write your own observer mechanism, not hard, but why when you dont have to and you can just use multicast events.
Nested types have access to the enclosing type's private and protected events. I've used this feature to notify child controls (the nested type) of state changes in the parent control (the enclosing type) in a Silverlight application.
Sorry to drag up an old thread, but I use private events with impunity in one of my projects, and personally, I find it's a good way of solving a design issue:
Here's the abbreviated code:
public class MyClass
{
private event EventHandler _myEvent;
public ExternalObject { get; set; }
public event EventHandler MyEvent
{
add
{
if (_myEvent.GetInvocationList().Length == 0 && value != null)
ExternalObject.ExternalEvent += HandleEvent;
_myEvent+= value;
}
remove
{
_myEvent-= value;
if (_myEvent.GetInvocationList().Length == 0)
ExternalObject.ExternalEvent -= HandleEvent;
}
}
private void HandleEvent(object sender, EventArgs e)
{
_myEvent.Raise(this, EventArgs.Empty); // raises the event.
}
}
Basically, MyEvent is only ever raised in the event handler of ExternalObject.ExternalEvent, so if there's no handlers for MyEvent then I don't need to attach a handler to the external event, speeding up the code slightly by saving a stack frame.
Not only the current instance can access a private member. Other instances of the same type can too! This enables some scenarios where this access control may be useful.
I am thinking of a tree structure where all nodes inherit a certain type and a private/protected event allows to propagate leaf events to their parents. Since they are the same type, the parent can register to the child's private event. Yet any client of the tree structure cannot.
I can definitely see a use case in a directory like storage system where where each directory needs to propagate its last modified date to its parent for example.