Open sandboxFocusImprove this doc

LA0193: Introduced Attribute Type Name Is Not Assembly-Qualified

Severity Error
Reported by PostSharp
Message Cannot apply the aspect "<Aspect>" to target "<Target>": the type name "<TypeName>" of the custom attribute to introduce is not an assembly-qualified type name. Include the name of the assembly, or create the ObjectConstruction from a Type.

Cause

An aspect provider introduces a custom attribute by providing a CustomAttributeIntroductionAspect, which receives the attribute as a ObjectConstruction. When the ObjectConstruction is created from a type name, PostSharp needs the name of the assembly to find the type, so the name must be assembly-qualified, such as MyCompany.AuditTrailAttribute, MyCompany.Core. PostSharp reports LA0193 when the name has no assembly part.

<Aspect> is CustomAttributeIntroductionAspect, not the aspect that provides it, and <Target> is the declaration that should receive the attribute.

In the following example, the [Audited] aspect introduces the AuditTrail attribute by its namespace and type name only.

using System;
using System.Collections.Generic;
using PostSharp.Aspects;
using PostSharp.Reflection;
using PostSharp.Serialization;

namespace Errors.LA0193_Error;

[AttributeUsage( AttributeTargets.Method )]
public class AuditTrailAttribute : Attribute
{
}

[PSerializable]
public class AuditedAttribute : MethodLevelAspect, IAspectProvider
{
    public IEnumerable<AspectInstance> ProvideAspects( object targetElement )
    {
        // The type name of the attribute does not include the name of its assembly.
        var attribute = new ObjectConstruction( "Errors.LA0193_Error.AuditTrailAttribute" );

        yield return new AspectInstance( targetElement, new CustomAttributeIntroductionAspect( attribute ) );
    }
}

public class OrderService
{
    [Audited]
    public void PlaceOrder()
    {
    }
}

public static class Program
{
    public static void Main()
    {
        var method = typeof( OrderService ).GetMethod( nameof( OrderService.PlaceOrder ) )!;
        Console.WriteLine( $"PlaceOrder has [AuditTrail]: {Attribute.IsDefined( method, typeof( AuditTrailAttribute ) )}" );
    }
}
error LA0193: LA0193_Error.cs(29,17): Cannot apply the aspect "PostSharp.Aspects.CustomAttributeIntroductionAspect" to target "Errors.LA0193_Error.OrderService.PlaceOrder": the type name "Errors.LA0193_Error.AuditTrailAttribute" of the custom attribute to introduce is not an assembly-qualified type name. Include the name of the assembly, or create the ObjectConstruction from a Type.

Resolution

  • Create the ObjectConstruction from the Type of the attribute when the aspect can reference it: the constructor that takes a Type uses its assembly-qualified name.
  • Otherwise, add the name of the assembly to the type name, after a comma.

In the following example, the ObjectConstruction is created from typeof( AuditTrailAttribute ), and the program finds the attribute on PlaceOrder.

using System;
using System.Collections.Generic;
using PostSharp.Aspects;
using PostSharp.Reflection;
using PostSharp.Serialization;

namespace Errors.LA0193_Fixed;

[AttributeUsage( AttributeTargets.Method )]
public class AuditTrailAttribute : Attribute
{
}

[PSerializable]
public class AuditedAttribute : MethodLevelAspect, IAspectProvider
{
    public IEnumerable<AspectInstance> ProvideAspects( object targetElement )
    {
        // The Type gives the assembly-qualified name of the attribute.
        var attribute = new ObjectConstruction( typeof( AuditTrailAttribute ) );

        yield return new AspectInstance( targetElement, new CustomAttributeIntroductionAspect( attribute ) );
    }
}

public class OrderService
{
    [Audited]
    public void PlaceOrder()
    {
    }
}

public static class Program
{
    public static void Main()
    {
        var method = typeof( OrderService ).GetMethod( nameof( OrderService.PlaceOrder ) )!;
        Console.WriteLine( $"PlaceOrder has [AuditTrail]: {Attribute.IsDefined( method, typeof( AuditTrailAttribute ) )}" );
    }
}
PlaceOrder has [AuditTrail]: True

See Also

Reference

CustomAttributeIntroductionAspect
ObjectConstruction
IAspectProvider

Other Resources

Introducing Custom Attributes
Adding Aspects Programmatically Using IAspectProvider