c# - 可以拦截异步方法并覆盖 ReturnValue?
问题描述
我有一个方法:
public virtual async Task<IActionResult> GetEmployees([HttpTrigger(AuthorizationLevel.Admin, "get", Route = null)] HttpRequest req) {
return OkObjectResult(null);
}
我知道我可以使用 autofac 同步拦截:
public class CallLogger : IInterceptor
{
TextWriter _output;
public CallLogger(TextWriter output)
{
_output = output;
}
public void Intercept(IInvocation invocation)
{
_output.Write("Calling method {0} with parameters {1}... ",
invocation.Method.Name,
string.Join(", ", invocation.Arguments.Select(a => (a ?? "").ToString()).ToArray()));
invocation.Proceed();
_output.WriteLine("Done: result was {0}.", invocation.ReturnValue);
}
}
但是,如何在可能覆盖我正在拦截的方法返回的结果的同时异步执行此操作?它当前返回一个OkObjectResult
,例如,我可能想返回一个 404。
伪代码
public async Task Intercept(IInvocation invocation)
{
var myAsyncResult = await _myAsyncClass.MyAsyncMethod();
if (myAsyncResult == expected)
{
invocation.Proceed();
}
else
{
invocation.ReturnValue = // some overwrite of the value - and don't proceed with the invocation.
}
}
笔记
我知道在 autofac 中有聪明的异步方法,但这不允许我阻止执行原始方法并覆盖值,而是我需要“继续”调用并使用它的返回:https://stackoverflow。 com/a/39784559/12683473
解决方案
Castle.Core 要记住的主要事情是,您不能IInvocation.Proceed
在 an 之后调用,await
因为IInvocation
实例在拦截器(同步)返回后被重用。
但是,Castle.Core 的现代版本确实支持IInvocation.CaptureProceedInfo
,可以这样使用:
public class CallLogger : IInterceptor
{
public void Intercept(IInvocation invocation)
{
invocation.ReturnValue = InterceptAsync<MyResult>(invocation.CaptureProceedInfo());
}
private async Task<TResult> InterceptAsync<TResult>(IInvocationProceedInfo proceed)
{
var myAsyncResult = await _myAsyncClass.MyAsyncMethod();
if (myAsyncResult == expected)
{
proceed.Invoke();
}
else
{
return ...;
}
}
}
这个简单的代码假定您的代码可以指定一种类型MyResult
,该类型是被拦截方法的已知结果。更一般的情况需要反思和TaskCompletionSource<T>
.
推荐阅读
- google-drive-api - 我可以将 Google Drives list() 请求限制为在我的域中拥有的文件吗?
- windows - 我如何知道桌面显示的时间?
- angular - 响应式表单未使用第三方地址查找进行更新
- python - JSONDecodeError:使用 googletrans 模块
- oledb - 运算符/操作数类型不匹配
- java - 基于类型生成表单元素,并带有覆盖
- azure - TERRAFORM 如何在子网上设置 count.index 以检索 network_security_group_id
- c# - Unity 方法不会调用
- python - 可视化具有许多输入的 KMeans 聚类
- java - 多个编辑文本验证该字段是否包含在保存按钮中具有可见性的数据