Skip to content

Commit 6d232d3

Browse files
author
Nicholas Myers
authored
Merge pull request #1 from neekgreen/develop
Develop
2 parents d3469d5 + df20df0 commit 6d232d3

31 files changed

Lines changed: 645 additions & 11 deletions

Cacheable.sln

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,16 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{D1F536AC
1515
EndProject
1616
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Cacheable.Tests", "tests\Cacheable.Tests\Cacheable.Tests.csproj", "{D4F95B27-30B5-4391-8322-A456A7EE4EA5}"
1717
EndProject
18+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{FC7F7153-1BFC-476F-9AE6-C771F987D6B6}"
19+
EndProject
20+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "MediatR", "MediatR", "{A285DE98-56C9-4713-A033-EDC8BC65F110}"
21+
EndProject
22+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Cacheable.Microsoft.Extensions.Caching.Abstractions", "src\Cacheable.Microsoft.Extensions.Caching.Abstractions\Cacheable.Microsoft.Extensions.Caching.Abstractions.csproj", "{F665B4DB-4416-41CE-AF82-F05CFC709067}"
23+
EndProject
24+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Cacheable.MediatR", "src\Cacheable.MediatR\Cacheable.MediatR.csproj", "{126F7A77-6F66-4235-A8A4-76B416ED712E}"
25+
EndProject
26+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WebApiDotNetCore20", "samples\MediatR\WebApiDotNetCore20\WebApiDotNetCore20.csproj", "{1109466A-4366-44C6-908B-8A43053860B8}"
27+
EndProject
1828
Global
1929
GlobalSection(SolutionConfigurationPlatforms) = preSolution
2030
Debug|Any CPU = Debug|Any CPU
@@ -29,12 +39,26 @@ Global
2939
{D4F95B27-30B5-4391-8322-A456A7EE4EA5}.Debug|Any CPU.Build.0 = Debug|Any CPU
3040
{D4F95B27-30B5-4391-8322-A456A7EE4EA5}.Release|Any CPU.ActiveCfg = Release|Any CPU
3141
{D4F95B27-30B5-4391-8322-A456A7EE4EA5}.Release|Any CPU.Build.0 = Release|Any CPU
42+
{F665B4DB-4416-41CE-AF82-F05CFC709067}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
43+
{F665B4DB-4416-41CE-AF82-F05CFC709067}.Debug|Any CPU.Build.0 = Debug|Any CPU
44+
{F665B4DB-4416-41CE-AF82-F05CFC709067}.Release|Any CPU.ActiveCfg = Release|Any CPU
45+
{F665B4DB-4416-41CE-AF82-F05CFC709067}.Release|Any CPU.Build.0 = Release|Any CPU
46+
{126F7A77-6F66-4235-A8A4-76B416ED712E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
47+
{126F7A77-6F66-4235-A8A4-76B416ED712E}.Debug|Any CPU.Build.0 = Debug|Any CPU
48+
{126F7A77-6F66-4235-A8A4-76B416ED712E}.Release|Any CPU.ActiveCfg = Release|Any CPU
49+
{126F7A77-6F66-4235-A8A4-76B416ED712E}.Release|Any CPU.Build.0 = Release|Any CPU
50+
{1109466A-4366-44C6-908B-8A43053860B8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
51+
{1109466A-4366-44C6-908B-8A43053860B8}.Debug|Any CPU.Build.0 = Debug|Any CPU
52+
{1109466A-4366-44C6-908B-8A43053860B8}.Release|Any CPU.ActiveCfg = Release|Any CPU
53+
{1109466A-4366-44C6-908B-8A43053860B8}.Release|Any CPU.Build.0 = Release|Any CPU
3254
EndGlobalSection
3355
GlobalSection(SolutionProperties) = preSolution
3456
HideSolutionNode = FALSE
3557
EndGlobalSection
3658
GlobalSection(NestedProjects) = preSolution
3759
{D4F95B27-30B5-4391-8322-A456A7EE4EA5} = {8C6885A4-912E-4900-A809-EC9607DFA495}
60+
{A285DE98-56C9-4713-A033-EDC8BC65F110} = {FC7F7153-1BFC-476F-9AE6-C771F987D6B6}
61+
{1109466A-4366-44C6-908B-8A43053860B8} = {A285DE98-56C9-4713-A033-EDC8BC65F110}
3862
EndGlobalSection
3963
GlobalSection(ExtensibilityGlobals) = postSolution
4064
SolutionGuid = {E8200E84-166D-4FBF-90FD-9FAB13CE5191}

README.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
cacheable
2+
====================
3+
4+
[![Build status](https://ci.appveyor.com/api/projects/status/w91o128dbwdwvj8a?svg=true)](https://ci.appveyor.com/project/neekgreen/cacheable)
5+
[![NuGet](https://img.shields.io/nuget/v/cacheable.svg)](https://www.nuget.org/packages/cacheable)
6+
[![NuGet](https://img.shields.io/nuget/dt/cacheable.svg)](https://www.nuget.org/packages/cacheable)
7+
[![CodeFactor](https://www.codefactor.io/repository/github/neekgreen/cacheable/badge)](https://www.codefactor.io/repository/github/neekgreen/cacheable)
8+
9+
A set of extensions to provide caching support on MediatR based request handlers.
10+
11+
[![something](https://img.shields.io/badge/.netstandard-2.0-blue.svg)](https://img.shields.io/badge/.netstandard-1.3-blue.svg)
12+
13+
## Installing Cacheable
14+
15+
You should install [Cacheable with NuGet](https://www.nuget.org/packages/cacheable):
16+
17+
Install-Package Cacheable
18+
19+
This command will download and install Cacheable. Let me know if you have questions!
20+
21+
## Using Cacheable
22+
23+
Cacheable requires MediatR and your IoC container of choice. The decorator pattern is used to wrap the `IRequestHandler` and `IAsyncRequestHandler` classes with Cacheable implementations that will handle the caching.
24+
25+
### With StructureMap
26+
27+
```
28+
For(typeof(IRequestHandler<,>)).DecorateAllWith(typeof(MemoryCacheRequestHandler<,>));
29+
```
30+
31+
```
32+
For(typeof(IAsyncRequestHandler<,>)).DecorateAllWith(typeof(MemoryCacheAsyncRequestHandler<,>));
33+
```

build.sh

100644100755
File mode changed.
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
namespace WebApiDotNetCore20
2+
{
3+
using System.Diagnostics;
4+
using System.Threading.Tasks;
5+
using Microsoft.AspNetCore.Mvc.Filters;
6+
7+
public class BenchmarkAttribute : ActionFilterAttribute
8+
{
9+
public override async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
10+
{
11+
var stopWatch = new Stopwatch();
12+
stopWatch.Start();
13+
14+
await next();
15+
16+
stopWatch.Stop();
17+
context.HttpContext.Response.Headers.Add("x-time-elapsed", stopWatch.Elapsed.ToString());
18+
}
19+
}
20+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
namespace WebApiDotNetCore20.Features.NoCache
2+
{
3+
using MediatR;
4+
using Models;
5+
6+
public class Command : IRequest<Result>
7+
{
8+
public int Number { get; set; }
9+
}
10+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
namespace WebApiDotNetCore20.Features.NoCache
2+
{
3+
using System.Threading.Tasks;
4+
using MediatR;
5+
using Models;
6+
7+
public class CommandHandler : IAsyncRequestHandler<Command, Result>
8+
{
9+
private readonly IResultBuilder resultBuilder;
10+
11+
public CommandHandler(IResultBuilder resultBuilder)
12+
{
13+
this.resultBuilder = resultBuilder;
14+
}
15+
16+
Task<Result> IAsyncRequestHandler<Command, Result>.Handle(Command message)
17+
{
18+
return Task.FromResult(resultBuilder.GetResult(message.Number));
19+
}
20+
}
21+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
namespace WebApiDotNetCore20.Features.NoCache
2+
{
3+
using System.Threading.Tasks;
4+
using Microsoft.AspNetCore.Mvc;
5+
using MediatR;
6+
7+
[Route("api/no-cache")]
8+
public class TestController : Controller
9+
{
10+
private readonly IMediator mediator;
11+
12+
public TestController(IMediator mediator)
13+
{
14+
this.mediator = mediator;
15+
}
16+
17+
[Benchmark, HttpGet("{number}")]
18+
public async Task<IActionResult> Get(int number)
19+
{
20+
var result =
21+
await mediator.Send(new Command { Number = number });
22+
23+
return Ok(result);
24+
}
25+
}
26+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
namespace WebApiDotNetCore20.Features.WithCache
2+
{
3+
using System;
4+
using Cacheable;
5+
using MediatR;
6+
using Models;
7+
8+
public class Command : IRequest<Result>, ICacheableRequest
9+
{
10+
public int Number { get; set; }
11+
12+
public bool IsCacheable { get; set; } = true;
13+
14+
public string GetCacheKey() { return "number:" + Number; }
15+
16+
public CacheEntryOptions GetCacheOptions()
17+
{
18+
return new CacheEntryOptions { SlidingExpiration = TimeSpan.FromMinutes(5) };
19+
}
20+
}
21+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
namespace WebApiDotNetCore20.Features.WithCache
2+
{
3+
using Cacheable;
4+
using MediatR;
5+
using Models;
6+
7+
public class CommandHandler : IRequestHandler<Command, Result>, ICacheableRequestHandler
8+
{
9+
private readonly IResultBuilder resultBuilder;
10+
11+
public CommandHandler(IResultBuilder resultBuilder)
12+
{
13+
this.resultBuilder = resultBuilder;
14+
}
15+
16+
Result IRequestHandler<Command, Result>.Handle(Command message)
17+
{
18+
return resultBuilder.GetResult(message.Number);
19+
}
20+
}
21+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
namespace WebApiDotNetCore20.Features.WithCache
2+
{
3+
using System.Threading.Tasks;
4+
using Microsoft.AspNetCore.Mvc;
5+
using MediatR;
6+
7+
[Route("api/with-cache")]
8+
public class TestController : Controller
9+
{
10+
private readonly IMediator mediator;
11+
12+
public TestController(IMediator mediator)
13+
{
14+
this.mediator = mediator;
15+
}
16+
17+
[Benchmark, HttpGet("{number}")]
18+
public async Task<IActionResult> Get(int number, bool isCacheable)
19+
{
20+
var result =
21+
await mediator.Send(new Command { Number = number, IsCacheable = isCacheable });
22+
23+
return Ok(result);
24+
}
25+
}
26+
}

0 commit comments

Comments
 (0)