Skip to content

Commit 5cadf21

Browse files
committed
Simplify example.
1 parent c779350 commit 5cadf21

File tree

6 files changed

+89
-49
lines changed

6 files changed

+89
-49
lines changed

BlazorOutputCaching.ServiceInterface/MyServices.cs

+2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
using ServiceStack;
22
using BlazorOutputCaching.ServiceModel;
3+
using Microsoft.AspNetCore.OutputCaching;
34

45
namespace BlazorOutputCaching.ServiceInterface;
56

7+
[OutputCache(Duration = 60)]
68
public class MyServices : Service
79
{
810
public object Any(Hello request)

BlazorOutputCaching.ServiceModel/BlazorOutputCaching.ServiceModel.csproj

+6
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,10 @@
1414
<Folder Include="Types\" />
1515
</ItemGroup>
1616

17+
<ItemGroup>
18+
<Reference Include="Microsoft.AspNetCore.OutputCaching">
19+
<HintPath>..\..\..\..\.dotnet\packs\Microsoft.AspNetCore.App.Ref\8.0.2\ref\net8.0\Microsoft.AspNetCore.OutputCaching.dll</HintPath>
20+
</Reference>
21+
</ItemGroup>
22+
1723
</Project>

BlazorOutputCaching/BlazorOutputCaching.csproj

+4
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@
4747
<Content Include="_videos\**" CopyToPublishDirectory="PreserveNewest" />
4848
</ItemGroup>
4949

50+
<ItemGroup>
51+
<Folder Include="App_Data\" />
52+
</ItemGroup>
53+
5054
<Target Name="tailwind" BeforeTargets="Publish">
5155
<Exec Command="npm run ui:build" WorkingDirectory="./" />
5256
</Target>

BlazorOutputCaching/Configure.AppHost.cs

-43
Original file line numberDiff line numberDiff line change
@@ -22,47 +22,4 @@ public override void Configure()
2222
}
2323
}
2424

25-
public class RedisOutputCacheStore : IOutputCacheStore
26-
{
27-
private readonly IRedisClientsManager _redisManager;
28-
29-
public RedisOutputCacheStore(IRedisClientsManager redisManager)
30-
{
31-
_redisManager = redisManager;
32-
}
33-
34-
public async ValueTask<byte[]?> GetAsync(string key, CancellationToken cancellationToken)
35-
{
36-
await using var redis = await _redisManager.GetClientAsync(token: cancellationToken);
37-
var value = await redis.GetAsync<byte[]>(key, cancellationToken);
38-
return value;
39-
}
40-
41-
public async ValueTask SetAsync(string key, byte[] value, string[]? tags, TimeSpan validFor, CancellationToken cancellationToken)
42-
{
43-
await using var redis = await _redisManager.GetClientAsync(token: cancellationToken);
44-
45-
// First persist in normal cache hashset
46-
await redis.SetAsync(key, value, validFor, cancellationToken);
47-
48-
if (tags == null)
49-
return;
50-
foreach (var tag in tags)
51-
{
52-
await redis.AddItemToSetAsync($"tag:{tag}", key, cancellationToken);
53-
}
54-
}
5525

56-
public async ValueTask EvictByTagAsync(string tag, CancellationToken cancellationToken)
57-
{
58-
await using var redis = await _redisManager.GetClientAsync(token: cancellationToken);
59-
60-
var keys = await redis.GetAllItemsFromListAsync($"tag:{tag}", cancellationToken);
61-
62-
foreach (var key in keys)
63-
{
64-
await redis.RemoveEntryAsync(key);
65-
await redis.RemoveItemFromSetAsync($"tag:{tag}", key, cancellationToken);
66-
}
67-
}
68-
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
using Microsoft.AspNetCore.OutputCaching;
2+
using ServiceStack.Redis;
3+
4+
[assembly: HostingStartup(typeof(BlazorOutputCaching.ConfigureOutputCache))]
5+
6+
namespace BlazorOutputCaching;
7+
8+
public class ConfigureOutputCache : IHostingStartup
9+
{
10+
public void Configure(IWebHostBuilder builder)
11+
{
12+
builder.ConfigureServices(services =>
13+
{
14+
services.AddSingleton<IRedisClientsManager>(c =>
15+
new BasicRedisClientManager("localhost:6379"));
16+
services.AddSingleton<IOutputCacheStore, RedisOutputCacheStore>();
17+
});
18+
}
19+
}
20+
21+
public class RedisOutputCacheStore(IRedisClientsManager redisManager) : IOutputCacheStore
22+
{
23+
public async ValueTask<byte[]?> GetAsync(string key, CancellationToken cancellationToken)
24+
{
25+
await using var redis = await redisManager.GetClientAsync(token: cancellationToken);
26+
var value = await redis.GetAsync<byte[]>(key, cancellationToken);
27+
return value;
28+
}
29+
30+
public async ValueTask SetAsync(string key, byte[] value, string[]? tags, TimeSpan validFor, CancellationToken cancellationToken)
31+
{
32+
await using var redis = await redisManager.GetClientAsync(token: cancellationToken);
33+
34+
// First persist in normal cache hashset
35+
await redis.SetAsync(key, value, validFor, cancellationToken);
36+
37+
if (tags == null)
38+
return;
39+
foreach (var tag in tags)
40+
{
41+
await redis.AddItemToSetAsync($"tag:{tag}", key, cancellationToken);
42+
}
43+
}
44+
45+
public async ValueTask EvictByTagAsync(string tag, CancellationToken cancellationToken)
46+
{
47+
await using var redis = await redisManager.GetClientAsync(token: cancellationToken);
48+
49+
var keys = await redis.GetAllItemsFromListAsync($"tag:{tag}", cancellationToken);
50+
51+
foreach (var key in keys)
52+
{
53+
await redis.RemoveEntryAsync(key);
54+
await redis.RemoveItemFromSetAsync($"tag:{tag}", key, cancellationToken);
55+
}
56+
}
57+
}

BlazorOutputCaching/Program.cs

+20-6
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@
1717
var services = builder.Services;
1818
var config = builder.Configuration;
1919

20-
services.AddSingleton<IRedisClientsManager>(new BasicRedisClientManager());
21-
services.AddSingleton<IOutputCacheStore, RedisOutputCacheStore>();
20+
//services.AddSingleton<IRedisClientsManager>(new BasicRedisClientManager());
21+
//services.AddSingleton<IOutputCacheStore, MemoryOutp>();
2222

2323
services.AddOutputCache();
2424

@@ -94,12 +94,26 @@
9494

9595
app.UseServiceStack(new AppHost(), options => {
9696
options.MapEndpoints();
97-
options.RouteHandlerBuilders.Add((handlerBuilder, operation, verb, route) =>
97+
options.RouteHandlerBuilders.Add((routeHandlerBuilder, operation, verb, route) =>
9898
{
99-
handlerBuilder.CacheOutput(policyBuilder =>
99+
// Initialize appHost and allServiceTypes
100+
var appHost = HostContext.AppHost;
101+
// Find the service matching the RequestType of the operation
102+
var operationType = operation.RequestType;
103+
// Match with operation, verb and route
104+
appHost.Metadata.OperationsMap.TryGetValue(operationType, out var operationMap);
105+
var serviceType = operationMap?.ServiceType;
106+
if (serviceType == null)
107+
return;
108+
if (serviceType.HasAttributeOf<OutputCacheAttribute>())
100109
{
101-
policyBuilder.Cache().Expire(TimeSpan.FromSeconds(15));
102-
});
110+
// Handle duration from OutputCacheAttribute
111+
var outputCacheAttribute = serviceType.FirstAttribute<OutputCacheAttribute>();
112+
routeHandlerBuilder.CacheOutput(policyBuilder =>
113+
{
114+
policyBuilder.Cache().Expire(TimeSpan.FromSeconds(outputCacheAttribute.Duration));
115+
});
116+
}
103117
});
104118
});
105119

0 commit comments

Comments
 (0)