5

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

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

如果我像这样向方面添加一个属性:

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

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

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

4

2 回答 2

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;
}
于 2012-12-12T20:46:19.227 回答
0

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

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

于 2012-12-12T20:41:03.777 回答