Open sandboxFocusImprove this doc

CAC007: [InvalidateCache] Names No Method

Severity Error
Reported by PostSharp.Patterns.Caching
Message Invalid [InvalidateCache] aspect on <Method>: the constructor parameters should contain at least one method name.

Cause

The InvalidateCacheAttribute aspect removes from the cache the values of the cached methods whose names you pass to its constructor. The method names are a params array, so C# accepts the attribute without any argument, or with only the declaring type. The aspect then has nothing to invalidate, and PostSharp reports CAC007.

<Method> is the invalidating method, the one to which the aspect is applied. PostSharp reports the message on the declaration of this method.

In the following example, the [InvalidateCache] aspect of RenameCustomer has no argument.

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

namespace Errors.CAC007_Error;

public class CustomerService
{
    private readonly Dictionary<int, string> names = new() { [1] = "Alice" };

    [Cache]
    public string GetCustomerName( int customerId )
    {
        Console.WriteLine( $"Loading customer {customerId} from the database." );

        return this.names[customerId];
    }

    // The aspect does not name the methods to invalidate.
    [InvalidateCache]
    public void RenameCustomer( int customerId, string name )
    {
        this.names[customerId] = name;
    }
}

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

        var service = new CustomerService();
        Console.WriteLine( service.GetCustomerName( 1 ) );
        Console.WriteLine( service.GetCustomerName( 1 ) );
        service.RenameCustomer( 1, "Alicia" );
        Console.WriteLine( service.GetCustomerName( 1 ) );
    }
}
error CAC007: CAC007_Error.cs(22,17): Invalid [InvalidateCache] aspect on Errors.CAC007_Error.CustomerService.RenameCustomer(System.Int32, System.String): the constructor parameters should contain at least one method name.

Resolution

Pass the names of the cached methods that the invalidating method makes stale to the InvalidateCacheAttribute aspect, preferably with the nameof operator. When the cached methods belong to another type, pass this type as the first argument. If the method does not invalidate any cached method, remove the aspect.

In the following example, the aspect names GetCustomerName, and the call to RenameCustomer removes the cached name, so the last call loads it again.

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

namespace Errors.CAC007_Fixed;

public class CustomerService
{
    private readonly Dictionary<int, string> names = new() { [1] = "Alice" };

    [Cache]
    public string GetCustomerName( int customerId )
    {
        Console.WriteLine( $"Loading customer {customerId} from the database." );

        return this.names[customerId];
    }

    // The aspect names the cached method to invalidate.
    [InvalidateCache( nameof(GetCustomerName) )]
    public void RenameCustomer( int customerId, string name )
    {
        this.names[customerId] = name;
    }
}

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

        var service = new CustomerService();
        Console.WriteLine( service.GetCustomerName( 1 ) );
        Console.WriteLine( service.GetCustomerName( 1 ) );
        service.RenameCustomer( 1, "Alicia" );
        Console.WriteLine( service.GetCustomerName( 1 ) );
    }
}
Loading customer 1 from the database.
Alice
Alice
Loading customer 1 from the database.
Alicia

See Also

Reference

InvalidateCacheAttribute
CacheAttribute

Other Resources

Removing Items From the Cache