传递Func<>或类似于PostSharp方面

时间:2012-12-12 20:26:45

标签: c# .net postsharp

在我们公开WCF服务的外部边界中,我们将所有内部异常转换为FaultException。这是一个手动过程,通常每个实现都有一些独特的缺陷。对于每种暴露的方法,它都经过复制/粘贴和无意识修改(或忘记)。为了减少错误,我想创建一个可以捕获任何未处理异常的方面。

我们将内部异常映射到故障异常。如何向方面发送映射功能?

如果我在这个方面添加一个属性:

[Serializable]
public sealed class FaultExceptionConverter : OnExceptionAspect {
    public Func<Exception, FaultException> FaultConverter { get; set }
}

我不能(正如属性限制所预期的那样)将其初始化为[FaultExceptionConverter(FaultConverter = MyConversionMethod)](其中MyConversionMethod是可分配给Func<Exception, FaultException>的某种方法)。是否有任何模式可以将此类参数传递给方面?许多类型可以传递到方面。这是一个常见的问题吗?

如果碰巧有更好的方法来实现这一点,我将不胜感激。

2 个答案:

答案 0 :(得分:2)

我在方面实现中遇到了类似的令人沮丧的限制,我用来绕过它们的一种方法是让方面将它实现的类视为某种“提供者”类型,它可以回调到在运行时请求其他位。

因此,在您的情况下,我想象一个OnException覆盖看起来像;

public override void OnException(MethodExecutionArgs args)
{
    IFaultConverterProvider provider = args.Instance as IFaultConverterProvider;
    if (null != provider)
        Func<Exception, FaultException>exceptionConverterFunc = provider.GetFunc();
}

IFaultConverterProvider是您在属性类型上定义和实现的某个界面,以提供您缺少的额外参数。

然后,作为一个完整性检查,您可以在您的方面引入一些编译时验证,以确保它应用的类型实际实现此必需的接口;

public override bool CompileTimeValidate(Type type)
{
    if (!type.IsImplementationOf(typeof(IFaultConverterProvider )))
    {
        // The aspect must be in a type which implements IFaultConverterProvider 
        Message.Write(
            MessageLocation.Of(type),
            SeverityType.Error,
            "CUSTOM02",
            "Cannot apply [MyFaultExceptionAspect] to type {0} because it does not implement IFaultConverterProvider .", type);
            return false;
    }

    return true;
}

答案 1 :(得分:0)

不幸的是,您只能将bool,byte,char,short,int,long,float,double,string,Type和枚举器传递给Attribute。

作为一种变通方法,您可以将typeof(FaultConverterClass)作为类型传递给"MyConversionMethod"作为字符串,并使用反射调用您的转换方法(当然,仅在此方法为静态的情况下)。这听起来很“脏”,但您可以添加编译时验证方法存在并且具有预期的签名。