Open sandboxFocusImprove this doc

CAC011: Cached Method Cannot Receive the Caching Service from Dependency Injection

Severity Warning
Reported by PostSharp.Patterns.Caching
Message The <Aspect> aspect applied to <Method> uses the default caching service, CachingServices.DefaultService, because <Method> is <Kind>, and only the instance methods of classes receive the caching service from dependency injection. To change the severity of this message, set the StaticMethodFallbackSeverity property of [CacheConfiguration].

Cause

When the UseDependencyInjection property of a CacheConfigurationAttribute is true for a class, its base classes or its assembly, the objects of the class receive their ICachingService from their constructors, and the caching aspects of their methods use this service. A static method, or a method of a struct, has no such object. Its aspect uses DefaultService instead, and PostSharp reports CAC011 on the method, because its items do not go to the cache that the container provides.

<Aspect> is [Cache] or [InvalidateCache], and <Kind> is static or a method of a struct.

The severity of the message is the value of the StaticMethodFallbackSeverity property of the nearest CacheConfigurationAttribute that sets it: SeverityType.Warning by default, or SeverityType.Error. With SeverityType.None, PostSharp reports nothing.

In the following example, ExchangeRateProvider is configured to receive its caching service from dependency injection, but its cached method is static.

using System;
using PostSharp.Patterns.Caching;
using PostSharp.Patterns.Caching.Backends;

namespace Errors.CAC011_Error;

[CacheConfiguration( UseDependencyInjection = true )]
public class ExchangeRateProvider
{
    [Cache]
    public static decimal GetRate( string currency ) // A static method has no instance that receives the caching service.
    {
        Console.WriteLine( $"Downloading the rate of {currency}." );

        return 1.08m;
    }
}

public static class Program
{
    public static void Main()
    {
        CachingServices.DefaultService.Backend = new MemoryCachingBackend();

        Console.WriteLine( ExchangeRateProvider.GetRate( "EUR" ) );
        Console.WriteLine( ExchangeRateProvider.GetRate( "EUR" ) );
    }
}
warning CAC011: CAC011_Error.cs(11,27): The [Cache] aspect applied to Errors.CAC011_Error.ExchangeRateProvider.GetRate(System.String) uses the default caching service, CachingServices.DefaultService, because Errors.CAC011_Error.ExchangeRateProvider.GetRate(System.String) is static, and only the instance methods of classes receive the caching service from dependency injection. To change the severity of this message, set the StaticMethodFallbackSeverity property of [CacheConfiguration].

Resolution

In the following example, GetRate is an instance method. The program creates the provider with new rather than with a container, so the provider receives the caching service registered in RunTimeServiceLocator.

using System;
using PostSharp.Extensibility;
using PostSharp.Patterns.Caching;
using PostSharp.Patterns.Caching.Backends;

namespace Errors.CAC011_Fixed;

[CacheConfiguration( UseDependencyInjection = true )]
public class ExchangeRateProvider
{
    [Cache]
    public decimal GetRate( string currency ) // An instance method uses the caching service that its object receives.
    {
        Console.WriteLine( $"Downloading the rate of {currency}." );

        return 1.08m;
    }
}

public static class Program
{
    public static void Main()
    {
        // An object created with new, rather than by a container, receives the service that RunTimeServiceLocator returns.
        var cachingService = new CachingService( new MemoryCachingBackend() );
        RunTimeServiceLocator.RegisterService<ICachingService>( () => cachingService );

        var provider = new ExchangeRateProvider();
        Console.WriteLine( provider.GetRate( "EUR" ) );
        Console.WriteLine( provider.GetRate( "EUR" ) );
    }
}
Downloading the rate of EUR.
1.08
1.08

See Also

Reference

UseDependencyInjection
StaticMethodFallbackSeverity
DefaultService

Other Resources

Using Caching with Dependency Injection