diff --git a/doc/dev/doc/extensions/caching.md b/doc/dev/doc/extensions/caching.md index 5fe43e3fe2..c9cdd93e74 100644 --- a/doc/dev/doc/extensions/caching.md +++ b/doc/dev/doc/extensions/caching.md @@ -51,4 +51,18 @@ With these declarations, the Hazelcast cache implementation would be injected in ## Cache Functionality -Hazelcast's implementation of `IDistributedCache` supports all functionality of the interface. Note however that, due to the inherently asynchronous nature of the Hazelcast client, all synchronous cache operations have to be implemented over asynchronous operations using the `task.GetAwaiter().GetResult()` pattern. This pattern can cause potential threading problems, and should be avoided as much as possible. Always use the asynchronous API wherever possible. \ No newline at end of file +Hazelcast's implementation of `IDistributedCache` supports all functionality of the interface. Note however that, due to the inherently asynchronous nature of the Hazelcast client, all synchronous cache operations have to be implemented over asynchronous operations using the `task.GetAwaiter().GetResult()` pattern. This pattern can cause potential threading problems, and should be avoided as much as possible. Always use the asynchronous API wherever possible. + +## ASP.NET Core Session State Provider +`IDistributedCache` implementation can be used to store session state in Hazelcast. After registering +Hazelcast `IDistributedCache` implementation to DI (as described above) you can enabled session state management +in your ASP.NET Core project. + +```csharp +var builder = WebApplication.CreateBuilder(args); +builder.Services.AddHazelcastCache(); +var app = builder.Build(); +app.UseSession(); // Session state will be stored in distributed cache provided by AddHazelcastCache() +``` +> [!WARNING] +> When the ISession object is supported by the Hazelcast client, its synchronous operations should be avoided, as the Hazelcast client is fully asynchronous and therefore calls to task.GetAwaiter().GetResult() may be involved and, potentially, cause threading issues. Prefer the asynchronous operations, such as those provided in the SessionExtensions class. diff --git a/src/Hazelcast.Net.Caching/Hazelcast.Net.Caching.csproj b/src/Hazelcast.Net.Caching/Hazelcast.Net.Caching.csproj index ebf6e42550..a483c3b8ea 100644 --- a/src/Hazelcast.Net.Caching/Hazelcast.Net.Caching.csproj +++ b/src/Hazelcast.Net.Caching/Hazelcast.Net.Caching.csproj @@ -44,6 +44,8 @@ + + diff --git a/src/Hazelcast.Net.Caching/Session/SessionExtensions.cs b/src/Hazelcast.Net.Caching/Session/SessionExtensions.cs new file mode 100644 index 0000000000..daa4a122b2 --- /dev/null +++ b/src/Hazelcast.Net.Caching/Session/SessionExtensions.cs @@ -0,0 +1,68 @@ +// Copyright (c) 2008-2022, Hazelcast, Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +using System.Threading; +using System.Threading.Tasks; +using Hazelcast.Core; +using Microsoft.AspNetCore.Http; + +namespace Hazelcast.Caching.Session; + +/// +/// This class wraps ISession extensions in the Microsoft.AspNetCore.Http.Extensions with LoadAsync call. +/// +public static class SessionExtensions +{ + /// + /// Gets a string value from . + /// + /// It loads the session as async. It is strongly advised to use async extensions over Hazelcast distributed + /// cache implementation. + /// The . + /// The key to read. + /// /// Cancellation Token + public static async Task GetStringAsync(this ISession session, string key, CancellationToken token = default) + { + await session.LoadAsync(token).CfAwait(); + return session.GetString(key); + } + + /// + /// Gets an int value from . + /// It loads the session as async. It is strongly advised to use async extensions over Hazelcast distributed + /// cache implementation. + /// + /// The . + /// The key to read. + /// Cancellation Token + public static async Task GetInt32Async(this ISession session, string key, CancellationToken token = default) + { + await session.LoadAsync(token).CfAwait(); + return session.GetInt32(key); + } + + /// + /// Gets a byte-array value from . + /// It loads the session as async. It is strongly advised to use async extensions over Hazelcast distributed + /// cache implementation. + /// + /// The . + /// The key to read. + /// Cancellation Token + public static async Task GetAsync(this ISession session, string key, CancellationToken token = default) + { + await session.LoadAsync(token).CfAwait(); + return session.Get(key); + } +}