版本我们选择5.0.0 (因为) 目前 AspectCore 依赖 Microsoft.Extensions.DependencyInjection 的版本是5.0.0 如何使用6.0
并且在Di里面引用
using AspectCore.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;
namespace Malema.Net;
public class DIConfig
{
public static IServiceProvider GetServiceProvider()
{
var services = new ServiceCollection();
services.AddScoped<ITestService, TestService>();
// 注入IMemoryCache。下面的 CacheInterceptorAttribute 会用到它
services.AddMemoryCache();
//return services.BuildServiceProvider();
return services.BuildDynamicProxyProvider();
}
}
using AspectCore.DynamicProxy;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.DependencyInjection;
using System.Text;
namespace Malema.Net;
public class CacheInterceptorAttribute : AbstractInterceptorAttribute
{
public override async Task Invoke(AspectContext context, AspectDelegate next)
{
var methodName = context.ImplementationMethod.DeclaringType + context.ImplementationMethod.Name;
var sb = new StringBuilder();
foreach (var item in context.ServiceMethod.GetParameters())
{
sb.Append(item.Name);
}
foreach (var value in context.Parameters)
{
sb.Append(value.GetHashCode());
}
var cacheKey = methodName + sb.ToString();
var cache = context.ServiceProvider.GetService<IMemoryCache>(); //在容器当中取出 IMemoryCache
var result = await cache.GetOrCreateAsync(cacheKey, async (entry) =>
{
await next(context);
var returnValue = context.ReturnValue;
return returnValue;
});
context.ReturnValue = result;
}
}
namespace Malema.Net;
public interface ITestService
{
string TestCache(int age);
Task<string> TestCacheAsync(int age);
}
namespace Malema.Net;
public class TestService : ITestService
{
[CacheInterceptor]
public string TestCache(int age)
{
Console.WriteLine("TestCache");
return (age + 100).ToString();
}
// Async方法也是支持的。
[CacheInterceptor]
public async Task<string> TestCacheAsync(int age)
{
Console.WriteLine("TestCacheAsync");
return (age + 200).ToString();
}
}
using Malema.Net;
using Microsoft.Extensions.DependencyInjection;
var sp = DIConfig.GetServiceProvider();
var service = sp.GetService<ITestService>();
var name = service.TestCache(30);
var name2 = service.TestCache(30);
Console.WriteLine($"Done {name2}");
name = await service.TestCacheAsync(30);
name2 = await service.TestCacheAsync(30);
Console.WriteLine($"Async Done {name2}");
Console.ReadKey();
输出
TestCache
Done 130
TestCacheAsync
Async Done 230
TestCache和TestCacheAsync只输出一次。其它值是从Cache当中获取的
完整的代码在https://gitee.com/malema/Examples/tree/AspectCore%2FCache/AspectCore-Example这边可以看到 可以用下面的git命令把代码签出到本地
git clone https://gitee.com/malema/Examples
git checkout AspectCore/Cache
如果引用 Microsoft.Extensions.Caching.Memory 6.0.0 我们会发现编译的时候会出现如下的错误
类型“ServiceCollection”同时存在于“Microsoft.Extensions.DependencyInjection.Abstractions, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60”
和“Microsoft.Extensions.DependencyInjection, Version=5.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60”中
如何解决这个错呢?
.Net的库很多时候是会兼容旧的。所以上面如果想使用 Microsoft.Extensions.Caching.Memory 6.0.0的版本的话
我们可以使用Nuget添加一个新的Package Microsoft.Extensions.DependencyInjection 6.0.0
这样上面的错误就会被解决了。