In my domain layer all domain objects emit events (of type InvalidDomainObjectEventHandler) to indicate invalid state when the IsValid property is called.
On an aspx codebehind, I have to manually wire up the events for the domain object like this:
_purchaseOrder.AmountIsNull += new DomainObject.InvalidDomainObjectEventHandler(HandleDomainObjectEvent);
_purchaseOrder.NoReason += new DomainObject.InvalidDomainObjectEventHandler(HandleDomainObjectEvent);
_purchaseOrder.NoSupplier += new DomainObject.InvalidDomainObjectEventHandler(HandleDomainObjectEvent);
_purchaseOrder.BothNewAndExistingSupplier += new DomainObject.InvalidDomainObjectEventHandler(HandleDomainObjectEvent);
Note that the same method is called in each case since the InvalidDomainobjectEventArgs class contains the message to display.
Is there any way I can write a single statement to wire up all events of type InvalidDomainObjectEventHandler in one go?
Thanks
David
I don't think you can do this in a single statement.. But you can make the code more readible like this:
_purchaseOrder.AmountIsNull += HandleDomainObjectEvent;
_purchaseOrder.NoReason += HandleDomainObjectEvent;
_purchaseOrder.NoSupplier += HandleDomainObjectEvent;
_purchaseOrder.BothNewAndExistingSupplier += HandleDomainObjectEvent;
Other than that - seems like the answer's no :(
You can create an aggregate event in some base class (or in some helper class, or in the PurchaseOrder
class itself, if you have access to it):
abstract class BaseOrderPage : Page {
PurchaseOrder _purchaseOrder = new PurchaseOrder();
...
public event InvalidDomainObjectEventHandler InvalidDomainObjectEvent {
add {
_purchaseOrder.AmountIsNull += value;
_purchaseOrder.NoReason += value;
_purchaseOrder.NoSupplier += value;
_purchaseOrder.BothNewAndExistingSupplier += value;
}
remove {
_purchaseOrder.AmountIsNull -= value;
_purchaseOrder.NoReason -= value;
_purchaseOrder.NoSupplier -= value;
_purchaseOrder.BothNewAndExistingSupplier -= value;
}
}
}
And then just use it in the derived classes:
InvalidDomainObjectEvent += new DomainObject.InvalidDomainObjectEventHandler(HandleDomainObjectEvent);
C# 2.0 and above:
InvalidDomainObjectEvent += HandleDomainObjectEvent;
I've used this technique successfully to aggregate events of the FileSystemWatcher
class.
You can use reflection to do this automatically. I think you want something like this:
public static void WireEvents(object subject)
{
Type type = subject.GetType();
var events = type.GetEvents()
.Where(item => item.EventHandlerType == typeof(InvalidDomainObjectEventHandler));
foreach (EventInfo info in events)
info.AddEventHandler(subject, new InvalidDomainObjectEventHandler(HandleDomainObjectEvent));
}
Then, all you have to do when you create a new object is this:
PurchaseOrder _purchaseOrder = new PurchaseOrder();
HelperClass.WireEvents(_purchaseOrder);
Don't forget that there is a performance penalty with reflection that will be apparent if you create PurchaseOrder
s and other similar objects in any great numbers.
Edit - other notes: you will need a using System.Reflection
directive. As it stands, this code needs C#3 for the var
keyword and .net framework 3.5 for the Where()
method (and - if it's not automatically generated - using System.Linq;
).
As David has done in a later answer, it can be re-written without changing the basic functionality for earlier versions.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With