前言
今天的第三篇,感觉没啥人看呀,难道没有兄弟跟我有同样的整合需求吗???手动
,
本文会简短一些,介绍下 CastleCore 作为代理库的一些缺点甚至是硬伤
异步支持
先上代码
/// <summary>
/// 异常捕获、日志记录和耗时监控 拦截器 2024-1-12 21:28:22
/// </summary>
public class CatchLoggingInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
//TODO:类注释所写的逻辑
Console.WriteLine("Interceptor starting...");
invocation.Proceed();
Console.WriteLine("Interceptor ended...");
}
}
如上是一个最简单的 CastleCore 拦截器示例,为了该拦截器能在使用的时候可以直接标注在方法上使用,为我们做如下改动:
/// <summary>
/// 异常捕获、日志记录和耗时监控 拦截器 2024-1-12 21:28:22
/// </summary>
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
public class CatchLoggingInterceptor : Attribute, IInterceptor
{
public void Intercept(IInvocation invocation)
{
//TODO:类注释所写的逻辑
Console.WriteLine("Interceptor starting...");
invocation.Proceed();
Console.WriteLine("Interceptor ended...");
}
}
public class SampleService : ISampleService
{
[CatchLoggingInterceptor]
public virtual Task<string> ShowAsync()
{
Console.WriteLine(nameof(ShowAsync));
return Task.FromResult(nameof(ShowAsync));
}
}
public interface ISampleService
{
[CatchLoggingInterceptor]
Task<string> ShowAsync();
}
使用代码如下
public static async Task Main(string[] args)
{
var services = new ServiceCollection();
services.AddLogging();//此处添加日志服务 伪代码 以便获取ILogger<SampleService>
services.TryAddSingleton(sp => new ProxyGenerator());
services.TryAddTransient<SampleService>();
services.TryAddTransient<ISampleService, SampleService>();
var sp = services.BuildServiceProvider();
var generator = sp.GetRequiredService<ProxyGenerator>();
var instance = sp.GetRequiredService<SampleService>();
var proxy = generator.CreateClassProxyWithTarget(typeof(SampleService), instance, new CatchLoggingInterceptor()) as SampleService;
var name = await proxy.ShowAsync();
}
输入如图所示:
name也可以正常取到值,没问题
看下拦截器的定义 ,我们全部是同步方法,要知道dotnetcore下是推荐所有方法都是异步的, 我们对拦截器做如下改造:
public void Intercept(IInvocation invocation)
{
invocation.ReturnValue = IntercetpAsync(invocation);
}
private async Task IntercetpAsync(IInvocation invocation)
{
//TODO:类注释所写的逻辑
await Console.Out.WriteLineAsync("Interceptor starting...");
Console.WriteLine("Interceptor starting...");
invocation.Proceed();
await Console.Out.WriteLineAsync("Interceptor ended...");
}
如上,拦截器里面使用Console.Out执行了异步方法的拦截,再执行
此时引出 Castle代理的致命的问题:拦截方法默认无法异步
针对此问题,官方也已显式标明,并提供了具体的解决办法
https://github.com/castleproject/Core/blob/master/docs/dynamicproxy-async-interception.md
这里我推荐 https://www.nuget.org/packages/stakx.DynamicProxy.AsyncInterceptor 的处理办法
其他缺点
- 拦截器内如何可以使用ioc的生态获取已经有的各项功能服务
- 某些场景下拦截器是需要传入常量 比方说,操作日志拦截,方法1 可能需要 Name="方法1",而方法二额需要 Name="方法2"
综上
上面三个缺点都是CastleCore 的硬伤,我们都要克服,后文会陆续解决这些问题,请各位看官拭目以待。写文很累,各位能不能dian点个star呢?您的鼓励会让我信心倍增,更新更快。
本文示例代码已上传至 https://gitee.com/gainorloss_259/microsoft-castle.git
- DependencyInjection Extensions Microsoft Castle Coredependencyinjection extensions microsoft castle dependenyinjection extensions microsoft castle extensions microsoft logging core windows windowsservices extensions microsoft extensions microsoft wpf extensions microsoft框架logging 第三方extensions microsoft logging 文件configuration extensions microsoft microsoft power core asp dependencyinjection