Open sandboxFocusImprove this doc

LA0274: Target Type Cannot Receive Dependencies

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 default creates 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