我已经和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,或者完全省略它们但我得到了同样的例外。
可以提供一些帮助。
干杯。
答案 0 :(得分:0)
根本原因是ILocationValidationAspect
无法应用于返回值。这种情况不受支持,但是你得到一个异常,而不是收到一条好的错误信息。
目前,必须使用OnMethodBoundary
方面(OnSuccess
建议)验证返回值。
如果要为开发人员提供单个自定义属性而不是两个,则可以使用此单个自定义属性实现IAspectProvider
,并使此方面提供两种实现之一。
请使用https://postsharp.uservoice.com/来请求此功能(ILocationValidationAspect应支持返回值)。
感谢。