Возможная ошибка в Postharp ReturnValue Расположение аспектов
Я работаю с PostSharp уже год, а недавно перешел на версию 3, у меня был большой успех в этом. Я пытаюсь расширить его усыновление в нашей компании, и убийственной чертой для усыновления будут атрибуты многоадресного контракта.
Я изучал PostSharp.Patterns.Contracts и написал для них MulticastAttributes, но есть некоторые вещи, которые вызывают трения при применении этих аспектов к нашему устаревшему коду, например, ArgumentNullException вместо ArgumentExceptions в некоторых проверках строк, но наиболее важным является то, что ReturnValues не может использовать эти атрибуты.
Я должен удвоить количество аспектов - один набор для параметров и один набор с одинаковыми валидациями, хотя и с разными исключениями, для ReturnValues с использованием OnMethodBoundaryAspect - что неприемлемо для наших разработчиков, поэтому я пытался разработать набор контрактов, которые может применяться как к параметрам, так и к возвращаемым значениям.
Я отмечаю, что 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 или опускал их вообще, но я получаю то же исключение.
Могли бы сделать с некоторой помощью.
Приветствия.
1 ответ
Коренная причина в том, что ILocationValidationAspect
не может быть применено к возвращаемым значениям. Этот сценарий не поддерживается, но вместо того, чтобы получить хорошее сообщение об ошибке, вы получите исключение.
В настоящее время возвращаемые значения должны быть проверены с использованием OnMethodBoundary
аспект (OnSuccess
консультировать).
Если вы хотите предоставить разработчикам один настраиваемый атрибут вместо двух, вы можете использовать этот единственный настраиваемый атрибут IAspectProvider
и иметь этот аспект, чтобы обеспечить одну из двух реализаций.
Пожалуйста, используйте https://postsharp.uservoice.com/ для запроса этой функции (ILocationValidationAspect должен поддерживать возвращаемые значения).
Благодарю.