0

我已经使用 PostSharp 一年了,最近升级到了第 3 版,我已经取得了很大的成功。我正在尝试扩大它在我们公司的采用范围,采用的杀手级功能将是多播合同属性。

我一直在研究 PostSharp.Patterns.Contracts 并为它们编写 MulticastAttributes 但在将这些方面应用于我们的遗留代码时有几件事会引起摩擦,例如在某些字符串验证中使用 ArgumentNullException 而不是 ArgumentExceptions 但最重要的是 ReturnValues不能使用这些属性。

对于使用 OnMethodBoundaryAspect 的 ReturnValues,我必须将方面的数量加倍——一组用于参数,一组具有相同的验证,尽管有不同的例外——这对我们的开发人员来说是不可接受的,所以我一直在尝试开发一组合同可以应用于参数和返回值。

我注意到 LocationContractAttribute 直接派生自 MulticastAttribute 并且只包含支持各种异常及其消息的代码,因此编写我自己的看起来像是一项简单的任务,但是当 Postsharp 在编译后启动时,以下简单方面给出了一个异常:

[AttributeUsage(AttributeTargets.ReturnValue),
    AspectConfiguration(SerializerType = typeof(MsilAspectSerializer)),
    MulticastAttributeUsage(
        MulticastTargets.ReturnValue
        , TargetMemberAttributes = MulticastAttributes.NonAbstract
        , Inheritance = MulticastInheritance.Multicast
        , PersistMetaData = true
    )]
public class SimpleReturnValueAttribute: MulticastAttribute,
    ILocationValidationAspect<string>
{
    public Exception ValidateValue(string value, string locationName, LocationKind locationKind)
    {
        return null;
    }
}

上课:

public class AspectTarget
{
        [return: SimpleReturnValue]
        public string ReturnEmptyString2()
        {
            return null;
        }
}

给出了例外:

Error   1   Unhandled exception (3.0.26.0, 32 bit, CLR 4.5, Release): System.NullReferenceException: Object reference not set to an instance of an object.
   at PostSharp.Sdk.CodeModel.MethodDefDeclaration.^bvoT7mPt9PXI(Int32 _0)
   at PostSharp.Sdk.AspectInfrastructure.CanonicalMethodMapping.^X0NY.EmitLoadArgument(Int32 _0, InstructionWriter _1)
   at ^670BgLZZ9jB2.^X5f4d1Yo.Implement(MethodBodyTransformationContext _0)
   at ^EbCRMdujK27A.^LuETqvLKzZPB(MetadataDeclaration _0, MetadataDeclaration _1, MethodSemantics _2, InstructionBlock _3, Object[] _4, CanonicalMethodMapping _5, LocalVariableSymbol _6, InstructionSequence _7, TypeDefDeclaration _8, PipelineTransversalState _9)
   at ^PE9ycIe2cLwm.^HvVDHXOj(MetadataDeclaration _0, IDependencyTransformationInstance[] _1, PipelineTransversalState _2, MethodSemantics _3)
   at PostSharp.Sdk.AspectInfrastructure.AspectInfrastructureTask.^jwku0geZ(MetadataDeclaration _0, PipelineTransversalState _1, MethodSemantics _2, Boolean _3)
   at PostSharp.Sdk.AspectInfrastructure.AspectInfrastructureTask.^MwzbegST(IMetadataDeclaration _0)
   at PostSharp.Sdk.AspectInfrastructure.StructuredDeclarationDictionary`1.^d+wOzSPF(IMetadataDeclaration _0, Func`2 _1)
   at PostSharp.Sdk.AspectInfrastructure.StructuredDeclarationDictionary`1.^+g+TCqVg(TypeDefDeclaration _0, Func`2 _1, Set`1 _2)
   at PostSharp.Sdk.AspectInfrastructure.StructuredDeclarationDictionary`1.^fJqG(Func`2 _0)
   at PostSharp.Sdk.AspectInfrastructure.AspectInfrastructureTask.Execute()
   at PostSharp.Sdk.Extensibility.Project.ExecutePhase(String phase)
   at PostSharp.Sdk.Extensibility.Project.Execute()
   at PostSharp.Hosting.PostSharpObject.ExecuteProjects()
   at PostSharp.Hosting.PostSharpObject.InvokeProject(ProjectInvocation projectInvocation)

从 LocationLevelAspect 派生方面会产生相同的错误。我也尝试了各种值 AspectConfiguration 和 PersistMetaData 或完全省略它们,但我得到了同样的例外。

可以做一些帮助。

干杯。

4

1 回答 1

0

根本原因是ILocationValidationAspect不能应用于返回值。不支持这种情况,但您不会收到一个很好的错误消息,而是会收到一个异常。

目前,必须使用OnMethodBoundary方面(OnSuccess建议)验证返回值。

如果您想为开发人员提供一个自定义属性而不是两个,您可以让这个自定义属性实现IAspectProvider,并让这个方面提供两个实现之一。

请使用https://postsharp.uservoice.com/请求此功能(ILocationValidationAspect 应支持返回值)。

谢谢。

于 2013-07-31T09:42:58.467 回答