2010-05-12 44 views
6

在我的域圖層中,當調用IsValid屬性時,所有域對象都會發出事件(類型爲InvalidDomainObjectEventHandler)以指示無效狀態。C#:在單個語句中連接來自對象的所有事件

在一個aspx代碼隱藏,我必須手動線了的域對象這樣的事件:

_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類型的所有事件?

感謝

大衛

回答

0

我看着Bob Sammers的建議。編譯器不順心的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)); 
    } 
    } 
} 

後,我加入這個方法的頁面,它所有的工作絕對hunky dory。而且我可以將事件添加到採購訂單對象,而無需記住單獨掛鉤,這正是我想要的。

5

我不認爲你可以在一個聲明中做到這一點..但是你可以讓這樣的代碼更readible:

_purchaseOrder.AmountIsNull += HandleDomainObjectEvent; 
_purchaseOrder.NoReason += HandleDomainObjectEvent; 
_purchaseOrder.NoSupplier += HandleDomainObjectEvent; 
_purchaseOrder.BothNewAndExistingSupplier += HandleDomainObjectEvent; 

比其他 - 似乎答案是:(

+0

'不能做'仍然是一個很好的答案! 謝謝 – David 2010-05-12 11:06:17

0

您可以考慮將事件處理程序放入界面中,然後附加界面:

public interface IPurchaseOrderObserver 
{ 
    void AmountIsNullEventHandler(WhateverArgs); 
    void NoReasonEventHandler(WhateverArgs); 
    void NoSupplierEventHandler(WhateverArgs); 
    void BothNewAndExistingSupplierEventHandler(WhateverArgs); 
} 

_purchaseOrder.RegisterObserver(DomainObject); 

您可以將這四行放入RegisterObeserver方法中,或者替換事件並直接調用接口。

+0

不知道我跟着這個,但似乎我仍然不得不直接提到所有事件的地方,如果不在網頁中的界面......是嗎? – David 2010-05-12 11:07:19

+0

是的,你需要提到所有的事件,但只在一個地方。 – 2010-05-17 10:57:30

2

您可以使用反射自動執行此操作。我想你想是這樣的:

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和其他類似對象,這一點將會很明顯。

編輯 - 其他注意事項:您將需要一個using System.Reflection指令。就目前而言,此代碼需要C#3的var關鍵字和.net framework 3.5的Where()方法(以及 - 如果它不是自動生成的 - using System.Linq;)。

正如David在稍後的回答中所做的那樣,可以在不更改早期版本的基本功能的情況下對其進行重新編寫。

+0

哇!我只能說謝謝! – David 2010-05-12 13:49:33

+0

我無法讓編譯器接受.Where方法,但我稍微重寫了您的代碼並重新發布了它。 非常感謝您的幫助! – David 2010-05-12 14:06:08

+0

嗯。我今天表現不佳!再一次,這段代碼已經過測試,而且我目前在我的代碼編輯器中有一份工作副本。我的猜測是我們不在同一個版本。你沒有說你的目標是什麼,但也許我應該說這個代碼只能在VS2008/.net3.5以上的版本上運行。 – 2010-05-12 14:21:11

3

您可以創建一些基礎類的聚集事件(或一些輔助類,或者在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; 

我使用第技術成功地聚合了events of the FileSystemWatcher類。

+0

我以前沒見過,謝謝! – David 2010-05-13 08:03:47