Возможная ошибка в 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 должен поддерживать возвращаемые значения).

Благодарю.

Другие вопросы по тегам