2012-05-31 16 views
3

我有一個類如何實現一個方法的先決條件?

public class MyService 
{ 
    public IList<Exception> ExList {get; private set;} 

    public bool HasErrors { get { return ExList.Count > 0; } } 

    public MyMethod() 
    { 
     ExList.Clear(); 
     //- do some logic --- 
    } 

} 

我想打電話的MyMethod(),並檢查錯誤發生了。這樣的事情

var service = new MyService(); 

service.MyMethod(); 

if(service.HasErrors) 
{ 
    // - do some logic 
} 

service.MyMethod(); 

if(service.HasErrors) 
{ 
    // - do some logic 
} 

但我必須寫「ExList.Clear();」爲MyService類中的每個方法提供了一些手動操作。 問題是 - 是否有解決方案來避免這種情況?

我需要這樣的東西

public class MyService 
{ 
    public IList<Exception> ExList {get; private set;} 

    public bool HasErrors { get { return ExList.Count > 0; } } 

    private void Precondition() 
    { 
     ExList.Clear(); 
    } 

    public MyMethod() 
    {   
     //- do some logic --- 
    } 

} 

和前提()會爲每個方法的調用自動調用。

+0

廣東話你拋出並捕獲異常?你會考慮使用它們嗎? – alexm

+0

因此,我必須將所有調用包裝到try {} catch {}中。它不適合我。如果在某些情況下我不想檢查錯誤呢? – Vyacheslav

+0

我需要類似CodeContracts([ContractInvariantMethod] private void ObjectInvariant(){})中實現的東西。但是隻有在方法執行後纔會調用 – Vyacheslav

回答

1

你可以看看的另一個工具是PostSharp。 PostSharp是一個AOP框架,允許您定義自定義方面(屬性)。

您會對OnMethodBoundaryAspect感興趣。像下面的東西應該做的伎倆。 args.Instance將

public class ClearListPrecondition : OnMethodBoundaryAspect 
{ 
    public override void OnEntry(MethodExecutionArgs args) 
    { 
     MyService service = args.Instance as MyService; 
     if (service == null) 
     { 
      throw new InvalidOperationException(
       "This aspect can only execute on types of MyService"); 
     } 

     service.ExList.Clear(); 
     base.OnEntry(args); 
    } 
} 

你會再裝點這個方面您的服務方法「上正在執行方法的實例」:

[ClearListPrecondition] 
public void MyMethod() 
{ 
} 

如果你選擇採取AOP的路徑對於這樣一個微不足道的任務,我強烈建議你重新考慮你的設計。首先,拋出異常應該是首選,但如果你堅持,你可以從你的方法返回一個結果。

E.g.

public MethodResult MyMethod() 
{ 
    .... 
    if(errorHasOccured) 
    { 
      return new MethodResult() {Exceptions = exception}; 
    } 
    .... 
    return new MethodResult() {ResultOfMethod = ...}; 
} 

public class MethodResult 
{ 
    public IList<Exception> Exceptions {get; set;} 
    public bool HasErrors { get { return ExList.Count > 0; } } 
    public string ResultOfMethod {get;set;} 

} 

你的消費者可以檢查方法調用的結果:

var service = new MyService(); 

var result1 = service.MyMethod(); 

if(result1.HasErrors) 
{ 
    // - do some logic 
} 

var result2 = service.MyMethod(); 

if(result2.HasErrors) 
{ 
    // - do some logic 
} 

這樣就省去了重置服務的狀態,因爲它成爲無狀態(因此線程)