Open sandboxFocusImprove this doc

CAC006: Null or Empty Method Name in [InvalidateCache]

Severity Error
Reported by PostSharp.Patterns.Caching
Message Invalid [InvalidateCache] aspect on <Method>: the constructor parameters cannot contain a null or empty string.

Cause

The InvalidateCacheAttribute aspect removes from the cache the values of the cached methods whose names you pass to its constructor. PostSharp looks up each name in the type that declares these methods. When one of the names is null or an empty string, PostSharp cannot look it up and reports CAC006. It stops validating the aspect at this point, so it does not check the other names.

<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 list of method names of the aspect ends with an empty string.

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

namespace Errors.CAC006_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 list of method names contains an empty string.
    [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 ) );
    }
}
error CAC006: CAC006_Error.cs(22,17): Invalid [InvalidateCache] aspect on Errors.CAC006_Error.CustomerService.RenameCustomer(System.Int32, System.String): the constructor parameters cannot contain a null or empty string.

Resolution

Pass only the names of cached methods to the InvalidateCacheAttribute aspect, and remove the null or empty ones. Prefer the nameof operator to string literals: the C# compiler then checks that each name exists.

In the following example, the aspect names only 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.CAC006_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];
    }

    // Every method name is the name of a cached method.
    [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