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 ---
   }

}

每个方法的调用都会自动调用 Precondition()。

4

1 回答 1

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 的道路来完成这样一个微不足道的任务,我强烈建议你重新思考你的设计。

首先,应该首选抛出异常,但如果您坚持,您可以从您的方法返回结果。

例如

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
}

这消除了重置服务状态的需要,因为它变得无状态(因此是线程安全的)

于 2012-06-05T10:28:09.377 回答