| Severity | Error |
| Reported by | PostSharp |
| Message | The aspect "<Aspect>" applied to "<Target>" attempts to introduce a dependency with ImportDependencyAdviceInstance, but "<TargetType>" cannot receive dependencies from its constructors. Dependencies are supported on classes that have instance constructors only. |
Cause
An ImportDependencyAdviceInstance makes the target class receive a service from its constructors: PostSharp adds a parameter of the service type to the instance constructors of the class, and stores the service in a field. PostSharp reports LA0274 when <TargetType>, the type to which the aspect is applied or the type that declares <Target>, has no such constructors:
- a static class, which has no instance constructor;
- a struct, which
defaultcreates without calling a constructor; - an interface or a delegate.
In the following example, the [Audited] aspect requests an IAuditLog for a method of a static class.
using System;
using System.Collections.Generic;
using System.Reflection;
using PostSharp.Aspects;
using PostSharp.Aspects.Advices;
using PostSharp.Extensibility;
using PostSharp.Serialization;
namespace Errors.LA0274_Error;
public interface IAuditLog
{
void Write( string message );
}
public sealed class ConsoleAuditLog : IAuditLog
{
public void Write( string message ) => Console.WriteLine( message );
}
[PSerializable]
public sealed class AuditedAttribute : MethodLevelAspect, IAdviceProvider
{
public IEnumerable<AdviceInstance> ProvideAdvices( object targetElement )
{
yield return new ImportDependencyAdviceInstance( typeof(IAuditLog) );
}
[OnMethodEntryAdvice]
public static void OnEntry( [Declaration] MethodBase method, [ImportMember] IAuditLog auditLog )
{
auditLog.Write( $"Executing {method.Name}." );
}
}
public static class PriceCalculator
{
// A static class has no constructor that could receive the IAuditLog.
[Audited]
public static decimal ApplyDiscount( decimal price, decimal rate ) => price * (1 - rate);
}
public static class Program
{
public static void Main()
{
RunTimeServiceLocator.RegisterService<IAuditLog>( () => new ConsoleAuditLog() );
Console.WriteLine( PriceCalculator.ApplyDiscount( 100m, 0.1m ) );
}
}
error LA0274: LA0274_Error.cs(40,27): The aspect "Errors.LA0274_Error.AuditedAttribute" applied to "Errors.LA0274_Error.PriceCalculator.ApplyDiscount(System.Decimal, System.Decimal)" attempts to introduce a dependency with ImportDependencyAdviceInstance, but "Errors.LA0274_Error.PriceCalculator" cannot receive dependencies from its constructors. Dependencies are supported on classes that have instance constructors only.
Resolution
- Make the target type a class with instance members, and create its objects with a dependency injection container, or with
new, which gets the service from RunTimeServiceLocator. - Otherwise, apply the aspect only to members of classes, or do not request the dependency on this target: the advice can get the service from GetRequiredService itself.
In the following example, PriceCalculator is an instance class, so new gets the IAuditLog from RunTimeServiceLocator.
using System;
using System.Collections.Generic;
using System.Reflection;
using PostSharp.Aspects;
using PostSharp.Aspects.Advices;
using PostSharp.Extensibility;
using PostSharp.Serialization;
namespace Errors.LA0274_Fixed;
public interface IAuditLog
{
void Write( string message );
}
public sealed class ConsoleAuditLog : IAuditLog
{
public void Write( string message ) => Console.WriteLine( message );
}
[PSerializable]
public sealed class AuditedAttribute : MethodLevelAspect, IAdviceProvider
{
public IEnumerable<AdviceInstance> ProvideAdvices( object targetElement )
{
yield return new ImportDependencyAdviceInstance( typeof(IAuditLog) );
}
[OnMethodEntryAdvice]
public static void OnEntry( [Declaration] MethodBase method, [ImportMember] IAuditLog auditLog )
{
auditLog.Write( $"Executing {method.Name}." );
}
}
public class PriceCalculator
{
// An instance class receives the IAuditLog from its constructor.
[Audited]
public decimal ApplyDiscount( decimal price, decimal rate ) => price * (1 - rate);
}
public static class Program
{
public static void Main()
{
RunTimeServiceLocator.RegisterService<IAuditLog>( () => new ConsoleAuditLog() );
Console.WriteLine( new PriceCalculator().ApplyDiscount( 100m, 0.1m ) );
}
}
Executing ApplyDiscount.
90.0
See Also
Reference
ImportDependencyAdviceInstance
RunTimeServiceLocator
Other Resources
Receiving Dependencies from the Constructors of the Target Class