我的目標是讓方法init()
和complete(result)
在選定類的每個方法之前和之後運行。 類似於ASP.NET中的ActionFilterAttribute
如何將OnActionExecuting
和OnActionExecuted
方法應用到應用它們的任何方法之前和之後。在每次調用接口之前和之後運行特定方法
有多個接口我想應用相同的init()
和complete(result)
方法,並且我希望避免代碼重複並儘可能讓代碼易於理解。
從我可以告訴,似乎沒有一個優雅的解決方案。到目前爲止,我有3個選項:
選項1:
public interface MyImportantMethods
{
object f();
object g();
}
public class MyClass : MyImportantMethods
{
public object f()
{
// Do things
}
public object g()
{
// Do things
}
}
public class WrappedMyClass : MyImportantMethods
{
private MyImportantMethods ActualContent;
public MyModifiedClass(MyImportantMethods actualContent)
{
this.ActualContent = actualContent;
}
public object f()
{
init();
object result = this.ActualContent.f();
complete(result);
return result;
}
public object g()
{
init();
object result = this.ActualContent.g();
complete(result);
return result;
}
}
- 優點:與實現的類是從 這就要求
init()
和complete()
了一個完全獨立的,所以它更易讀和易於理解。 - 缺點:不熟悉代碼的人很容易使用 錯誤的代碼。我希望 適用於每個接口需要不同的類。
選項2:
public interface MyImportantMethods
{
object f();
object g();
}
class Wrapper: IDisposable
{
public object result;
public Wrapper()
{
init();
}
void Dispose()
{
complete(result);
}
}
public class MyModifiedClass {
private void f()
{
using (var wrapper = new Wrapper(() => completeF()))
{
// Do Things
wrapper.result = result;
}
}
private void g()
{
using (var wrapper = new Wrapper(() => completeG()))
{
// Do Things
wrapper.result = result;
}
}
}
優點:不能使用了錯誤的類。有可能通過使用一個 IDisposable的類所有的接口,如果我使用一個反射招
缺點:代碼會顯得更加混亂,很難理解爲一個 新的讀者,特別是如果包裝的聲明發生多 行或包裝需要結果中的多個參數(在我的情況下,兩個 都是正確的)。也依靠調用者來設置結果。
方案3:
優點:不能使用了錯誤的類。具有 實現的類與調用init() 和complete()的類完全分離,因此它更易於理解並且更易於理解。
缺點:讀者不太容易理解。
難道真的沒有辦法像ActionFilterAttribute
那樣簡單易懂嗎?
恕我直言,選項3號是最好的,我不認爲這很難理解。當你提到ActionFilterAttribute時,爲什麼不創建一個屬性並在你的類中使用它? – Skaparate
我也喜歡Option3:很多程序員認可的Template Method設計模式的一個例子 – alexm
@Skaparate你需要一些使用屬性的東西 - 你不能指望只是添加幾個屬性就會奇蹟般地實現方法/接口攔截依賴注入控制器。如果你對OP很可能試圖做什麼感興趣,你可以看看它是如何完成Unity的(https://msdn.microsoft.com/en-us/library/dn178466(v=pandp.30).aspx)或者一般來說https://www.bing.com/search?q=c%23%20dependency%20injection%20interception –