這是EnterLib PIAB的BUG嗎?

2021-09-06 01:22:50 字數 3240 閱讀 9318

在預設的情況下,enterlib的piab採用基於transparentproxy/realproxy的機制實現對方法呼叫的攔截,進而實現了對橫切關注點(crosscutting concern)的動態注入。也正是其來截機制本身的侷限,當我們才用piab的方式進行物件的建立的時候,要求本建立物件的型別要麼實現某乙個介面,要麼繼承marshalbyrefobject型別。但是當我們讓抽象基類繼承自marshalbyrefobject就不行了,我個人覺得這是微軟需要改進的地方。

我們先來看看piab預設支援的程式設計方法。為此便於演示,我建立了乙個自定義的callhandler:foocallhandler。在invoke方法中,我在呼叫目標方法前後在控制台輸出相應的文字,表明該callhandler得以正常執行。下面是foocallhandler和它對應的handlerattributed的定義:

public

class foocallhandler : icallhandler

2:
10:
11:

public

int order

12: }
13:
14:

public

class foocallhandlerattribute : handlerattribute

15: ;
19:     }
20: }
先來模擬以及介面實現的程式設計方式,為此我們定義了乙個介面ifoo,實現該介面的型別foo。ifoo和foo定義在如下的**片斷中,上面建立的foocallhandler通過自定義特性的方式應用到型別foo上面。在main方法中,呼叫policyinjection的泛型方法create,並指明介面和具體型別的方式來建立foo物件。

1:

class program

2:
8:    }
9:

public

inte***ce ifoo

10:
13:    [foocallhandler]
14:

public

class foo : ifoo

15:
20:    }
從下面的輸出我們可以看出,應用在型別foo上面的foocallhandler在目標方法被呼叫之前先得到了執行。

1: preoperation...
2: do something...
3: postoperation...
你也可以讓foo直接繼承自marshalbyrefobject。如果你執行下面的**,你依然可以得到與上面一樣的輸出結果:

1:

class program

2:
8: }
9: [foocallhandler]
10:

public

class foo : marshalbyrefobject

11:
16: }

1:

class program

2:
8: }
9:
10:

public

abstract

class foobase

11:
14:
15: [foocallhandler]
16:

public

class foo: foobase

17:
22: }
上面的程式執行後,會丟擲如下圖所示的resolutionfailedexception異常。錯誤訊息表明異常是應該foobase不能被例項化導致的——foobase是抽象類。但是我們例項化的時具體型別foo,foobase能否例項化與此無關。

上面我們說過,能被piab進行攔截的型別要麼實現乙個介面,要麼繼承marshalbyreobject類。如果我們將foobase繼承自marshalbyreobject,是否會避免上述異常的丟擲呢?為此,我們對foobase加上了這個基類。

1:

public

abstract

class foobase: marshalbyrefobject

2:
執行我們的程式,會丟擲和上面完全一樣的異常。

四、抽象類可以這樣用

經過我的實驗,抽象類可以這樣用:將繼承自marshalbyrefobject的具體類作為抽象類的基類。按照這個原理,我們對上面的例子作了如下改動:將foobase從抽象類換成具體類,將foo變成抽象類(foo依然繼承自foobase),然後建立另乙個繼承自foo的具體類fooimpl。

1:

class program

2:
8: }
9:

public

class foobase: marshalbyrefobject

10:
15: }
16:

public

abstract

class foo : foobase

17: [foocallhandler]
18:

public

class fooimpl : foo

19:
24: }
作了如此修改後,執行我們的程式之後我們能夠得到正確的結果。不過,為了讓piab提供對抽象類的支援而多加上乙個非抽象的基類,在設計上是很醜陋的,我個人是不能接受的。實際上,我覺得這是piab自身的乙個bug,或者是自身欠考慮的地方。因為在實現的可行性上沒有任何問題。我親自在我自己開發的基於transparentproxy/realproxy的aop框架(《自己動手建立迷你版aop框架》)中經過驗證,讓抽象類繼承marshalbyrefobject,並基於該抽象類建立乙個可被攔截的transparentproxy物件是可以實現的。

artech

出處:

這是EnterLib PIAB的BUG嗎?

在預設的情況下,enterlib的piab採用基於transparentproxy realproxy的機制實現對方法呼叫的攔截,進而實現了對橫切關注點 crosscutting concern 的動態注入。也正是其來截機制本身的侷限,當我們才用piab的方式進行物件的建立的時候,要求本建立物件的型...

《EnterLib PIAB深入剖析》系列博文彙總

本篇文章介紹了整個piab的架構,並通過具體的例子揭示了piab的實現機制。如何建立你自己的callhandler 如何讓callhandler有序執行 由於本篇文章是基於enterprise library library v3.1 的,在該版本中,我們無法控制應用到同乙個目標方法上的多個call...

這是我們的土地

這 幾日裡的天總是灰濛濛的,前幾日有過沙塵暴,這幾日天氣突然又變得很冷了,對於那些生長在內蒙古的八零後的人們,這樣的天氣已經習慣了,對於那些更小的孩子來說或許他們還不知道十幾年前的內蒙古的春天不這樣的,而現在在他們的意識裡這春天的沙盡如夏天的雨,秋日的風,冬的雪來的一樣理所當然!不了解內蒙古的人說到...