Using Change Tokens In .NET 7

Introduction

Change tokens are a helpful feature in .NET 7 for tracking changes to a particular resource or piece of data. This can be useful for implementing caching or for other scenarios where you want to be notified when a resource has been modified. In this article, we'll look at how to use change tokens in .NET 7.

Creating a Change Token in .NET 7

To use change tokens in .NET 7, you'll need to create a class that implements the IChangeToken interface. This class should track the resource or data you want to be notified about when it changes.

Here's an example of a MyChangeToken class that implements the IChangeToken interface:

class MyChangeToken: IChangeToken {
    private string _resource;
    private bool _hasChanged;
    public MyChangeToken(string resource) {
        _resource = resource;
    }
    public bool HasChanged => _hasChanged;
    public bool ActiveChangeCallbacks => true;
    public IDisposable RegisterChangeCallback(Action < object > callback, object state) {
        // Register the callback to be invoked when the change token is triggered.
        // You can store the callback and state in a list or dictionary to keep track of all registered callbacks.
        return new MyDisposable();
    }
    private class MyDisposable: IDisposable {
        public void Dispose() {
            // Remove the callback from the list or dictionary when the IDisposable is disposed.
        }
    }
}
C#

In this example, the MyChangeToken class tracks a resource represented by a string. The HasChanged property returns a boolean value indicating whether the resource has been modified since the change token was created. The ActiveChangeCallbacks property should return true if the change token is currently tracking change callbacks, and false if it is not. The RegisterChangeCallback method registers a callback that will be invoked when the change token is triggered.

Creating a Change Token Instance

Once you've created a class that implements the IChangeToken interface, you can use ChangeToken.OnChange method to create a new change token instance. This method takes a delegate that returns an instance of the IChangeToken class, and an optional state object that will be passed to the change token's registered change callbacks.

Here's an example of how to create a new change token instance,

var changeToken = ChangeToken.OnChange(() => new MyChangeToken("my-resource"), null);
C#

Checking if the Resource Has Changed

You can use the HasChanged property of the IChangeToken interface to check if the resource or data tracked by the change token has been modified since the change token was created.

Here's an example of how to check if the resource has changed,

if (changeToken.HasChanged){
    // The resource has changed.
}
C#

Registering Change Callbacks

You can use the RegisterChangeCallback method of the IChangeToken interface to register a callback that will be invoked when the change token is triggered. This can be useful if you want to perform an action when the resource or data changes, rather than just being notified that it has changed.

Here's an example of how to register a change callback,

changeToken.RegisterChangeCallback((state) =>{
    // The resource has changed. This callback will be invoked when the change token is triggered.
}, null);
C#

In this example, the change callback is a delegate that takes an object as a parameter. This object is the state object that was passed to the ChangeToken.OnChange method when the change token was created.

Note that the RegisterChangeCallback method returns an IDisposable object. You can call the Dispose method of this object to unregister the change callback.

Imagine that you have a web application that displays data from a remote API. The data is updated frequently, so you want to cache it to improve performance and reduce the number of requests made to the API. However, you also want to be notified when the data has been updated so that you can refresh the cache.

Here's how you could use change tokens to implement this behavior:

Create a Cache class that implements the IChangeToken interface. The Cache class should store the cached data and track whether it has been modified.

When the cache is created, use ChangeToken.OnChange method to create a new change token instance for the cache.

In the Cache class, implement the HasChanged property to return a boolean value indicating whether the cache has been modified. You can set this value to true whenever the cache is updated.

In the web application, use the HasChanged property of the change token to check if the cache has been modified. If it has, retrieve the updated data from the API and refresh the cache.

You can also use the RegisterChangeCallback method to register a callback that will be invoked when the cache is updated. This callback can be used to refresh the cache and update the data displayed in the web application.

Here's some sample code that demonstrates how this might look,

class Cache: IChangeToken {
    private object _data;
    private bool _hasChanged;
    public Cache() {
        ChangeToken = ChangeToken.OnChange(() => this, null);
    }
    public IChangeToken ChangeToken {
        get;
    }
    public bool HasChanged => _hasChanged;
    public bool ActiveChangeCallbacks => true;
    public IDisposable RegisterChangeCallback(Action < object > callback, object state) {
        // Register the callback to be invoked when the cache is updated.
        // You can store the callback and state in a list or dictionary to keep track of all registered callbacks.
        return new MyDisposable();
    }
    private class MyDisposable: IDisposable {
        public void Dispose() {
            // Remove the callback from the list or dictionary when the IDisposable is disposed.
        }
    }
    public void Update(object data) {
        _data = data;
        _hasChanged = true;
        // Invoke the registered change callbacks.
        // You can iterate through the list or dictionary of registered callbacks and invoke each one.
    }
}
// In the web application:
var cache = new Cache();
if (cache.ChangeToken.HasChanged) {
    // The cache has been updated. Retrieve the updated data from the API and refresh the cache.
    var data = GetDataFromApi();
    cache.Update(data);
}
cache.ChangeToken.RegisterChangeCallback((state) => {
    // The cache has been updated. Refresh the cache and update the data displayed in the web application.
    var data = GetDataFromApi();
    cache.Update(data);
    UpdateDataInWebApplication(data);
}, null);
C#

Conclusion

Change tokens are a useful feature in .NET 7 for tracking changes to a particular resource or piece of data. You can use them to implement caching or other scenarios where you want to be notified when a resource has been modified. By creating a class that implements the IChangeToken interface, you can use the ChangeToken.OnChange method to create a new change token instance, and use the HasChanged property and RegisterChangeCallback method to track changes and register change callbacks.


Ramasagar Pulidindi

"Born from my early exploration of C/C++ and Java during B. Tech, my programming voyage has been a dynamic evolution. I've sculpted Windows Forms and web applications using C# ASP.NET, delved into the realms of ... Read more

https://www.c-sharpcorner.com/members/ramasagar-pulidindi