| 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
Typeuses 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