| 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
- Make the method an instance method of a class, and let the container create the objects of this class, so that the method uses the caching service of the container.
- If the method must stay static, or in a struct, and the default caching service is acceptable for it, set the StaticMethodFallbackSeverity property to SeverityType.None, and configure DefaultService at startup.
- To forbid the fallback in the whole project, set StaticMethodFallbackSeverity to SeverityType.Error on the assembly.
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