我已经使用 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 或完全省略它们,但我得到了同样的例外。
可以做一些帮助。
干杯。