В моем доменном слое все объекты области испускают события (типа InvalidDomainObjectEventHandler) для указания на недопустимое состояние, когда свойство IsValid называют.
На aspx codebehind, я должен вручную обеспечить электричеством события для объекта области как это:
_purchaseOrder.AmountIsNull += new DomainObject.InvalidDomainObjectEventHandler(HandleDomainObjectEvent);
_purchaseOrder.NoReason += new DomainObject.InvalidDomainObjectEventHandler(HandleDomainObjectEvent);
_purchaseOrder.NoSupplier += new DomainObject.InvalidDomainObjectEventHandler(HandleDomainObjectEvent);
_purchaseOrder.BothNewAndExistingSupplier += new DomainObject.InvalidDomainObjectEventHandler(HandleDomainObjectEvent);
Обратите внимание, что тот же метод называют в каждом случае, так как класс InvalidDomainobjectEventArgs содержит сообщение для отображения.
Есть ли какой-либо способ, которым я могу записать отдельного оператора для обеспечения электричеством всех событий типа InvalidDomainObjectEventHandler сразу?
Спасибо
David
Я посмотрел на предложение Боба Саммерса. Компилятору не понравился метод .Where для EventInfo [], возвращаемый GetEvents (), но я немного изменил код на следующий:
private void HookUpEvents()
{
Type purchaseOrderType = typeof (PurchaseOrder);
var events = purchaseOrderType.GetEvents();
foreach (EventInfo info in events)
{
if (info.EventHandlerType == typeof(Kctc.Data.Domain.DomainObject.InvalidDomainObjectEventHandler))
{
info.AddEventHandler(_purchaseOrder, new Kctc.Data.Domain.DomainObject.InvalidDomainObjectEventHandler(HandleDomainObjectEvent));
}
}
}
После того, как я добавил этот метод на страницу, все сработало абсолютно безупречно. дори. И я могу добавлять события к объекту заказа на покупку, не забывая подключать их по отдельности, а это именно то, что я хотел.
Не думаю, что это можно сделать в одном операторе... Но вы можете сделать код более читабельным, например, так:
_purchaseOrder.AmountIsNull += HandleDomainObjectEvent;
_purchaseOrder.NoReason += HandleDomainObjectEvent;
_purchaseOrder.NoSupplier += HandleDomainObjectEvent;
_purchaseOrder.BothNewAndExistingSupplier += HandleDomainObjectEvent;
В остальном - похоже, что ответ отрицательный :(
Вы можете использовать отражение, чтобы сделать это автоматически. Я думаю, вам нужно что-то вроде этого:
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));
}
Тогда все, что вам нужно сделать при создании нового объекта, это следующее:
PurchaseOrder _purchaseOrder = new PurchaseOrder();
HelperClass.WireEvents(_purchaseOrder);
Не забывайте, что есть снижение производительности с отражением, которое будет очевидным, если вы создадите PurchaseOrder
s и другие подобные объекты в любых больших количествах.
Правка - другие примечания: вам понадобится директива using System.Reflection
. В его нынешнем виде этому коду требуется C # 3 для ключевого слова var
и .net framework 3.5 для метода Where ()
(и - если он не создается автоматически - с использованием System.Linq;
).
Как Дэвид сделал в более позднем ответе, его можно переписать без изменения основных функций для более ранних версий.
Вы можете создать агрегированное событие в некоторых базовый класс (или в каком-то вспомогательном классе, или в самом классе PurchaseOrder
, если у вас есть к нему доступ):
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;
}
}
}
А затем просто используйте его в производных классах:
InvalidDomainObjectEvent += new DomainObject.InvalidDomainObjectEventHandler(HandleDomainObjectEvent);
C # 2.0 и выше :
InvalidDomainObjectEvent += HandleDomainObjectEvent;
Я успешно использовал эту технику для агрегирования событий класса FileSystemWatcher
.
Вы можете рассмотреть возможность поместить обработчики событий в интерфейс. Затем вы присоединяете интерфейс:
public interface IPurchaseOrderObserver
{
void AmountIsNullEventHandler(WhateverArgs);
void NoReasonEventHandler(WhateverArgs);
void NoSupplierEventHandler(WhateverArgs);
void BothNewAndExistingSupplierEventHandler(WhateverArgs);
}
_purchaseOrder.RegisterObserver(DomainObject);
Вы либо помещаете эти четыре строки в метод RegisterObeserver, либо заменяете события и напрямую вызываете интерфейсы.