使用Autofac在.NET Core 2.0 Web API控制器上进行拦截 [英] Interception on .NET Core 2.0 Web API Controller By Using Autofac
问题描述
我试图通过使用Autofac在.Net Core 2.0 WebApi应用程序上使用侦听,但是我无法在Controllers上成功使用它.我尝试的是
I am trying to use interceptions on .Net Core 2.0 WebApi Application by using Autofac but I couldnt succeed it on Controllers. What I try is
首先,我创建了一个基本的webapi,它具有一个默认控制器(ValuesController).然后,我按如下所示设置autofac配置.项目正在运行,没有任何错误,但是拦截似乎没有在运行.我做错了什么?
First I created a basic webapi which has one default controller(ValuesController). Then I set up the autofac configuration as below. Project is working without any error, but interception doesnt seems to be running. What I am doing wrong ?
Startup.cs
public void ConfigureContainer(ContainerBuilder builder)
{
builder.Register(c => new CallLogger());
builder.RegisterType<ValuesController>()
.EnableClassInterceptors()
.InterceptedBy(typeof(CallLogger));
}
CallLogger.cs
public class CallLogger : IInterceptor
{
public CallLogger()
{
System.Console.WriteLine("XXXXX");
}
public void Intercept(IInvocation invocation)
{
Console.WriteLine($"Calling method {invocation.Method.Name} with parameters {(string.Join(", ", invocation.Arguments.Select(a => (a ?? "").ToString()).ToArray()))}... ");
invocation.Proceed();
Console.WriteLine("Done: result was {0}.", invocation.ReturnValue);
}
}
ValuesController.cs
[Route("api/[controller]")]
[Intercept(typeof(CallLogger))]
public class ValuesController : Controller
{
private readonly ITest _test;
public ValuesController(ITest test)
{
_test = test;
}
// GET api/values
[HttpGet]
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
// GET api/values/5
[HttpGet("{id}")]
public string Get(int id, [FromHeader(Name = "TenantId")] string tenantId)
{
_test.Log("asdasdasda");
return tenantId + " => " + id;
}
// POST api/values
[HttpPost]
public void Post([FromBody]string value)
{
}
// PUT api/values/5
[HttpPut("{id}")]
public void Put(int id, [FromBody]string value)
{
}
// DELETE api/values/5
[HttpDelete("{id}")]
public void Delete(int id)
{
}
}
推荐答案
在处理类型拦截时,应将方法声明为虚拟
When working with interception of type, methods should be declared as virtual
在幕后,
EnableInterfaceInterceptors()
创建一个执行拦截的接口代理,而EnableClassInterceptors()
动态地将目标组件子类化以执行对虚拟方法的拦截.
Autofac文档-启用对类型的拦截
Under the covers,
EnableInterfaceInterceptors()
creates an interface proxy that performs the interception, whileEnableClassInterceptors()
dynamically subclasses the target component to perform interception of virtual methods.
Autofac documentation - Enable interception on types
即:
// GET api/values
[HttpGet]
public virtual IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
顺便说一句,您正在尝试拦截ASP.net核心控制器的方法.在这种情况下,默认情况下 Autofac 不会解析控制器
BTW you are trying to intercept method of ASP.net core controller. In this case controllers are not resolved by Autofac by default
默认情况下,ASP.NET Core会从容器中解析控制器参数,但实际上不会从容器中解析控制器.通常这不是问题,但这意味着:
By default, ASP.NET Core will resolve the controller parameters from the container but doesn’t actually resolve the controller from the container. This usually isn’t an issue but it does mean:
- 控制器的生命周期由框架处理,而不是请求生存期.
- 控制器构造函数参数的生命周期由请求生命周期处理.
- 您在控制器注册过程中可能进行的特殊接线(例如,设置属性注入)将不起作用.
- The lifecycle of the controller is handled by the framework, not the request lifetime.
- The lifecycle of controller constructor parameters is handled by the request lifetime.
- Special wiring that you may have done during registration of the controller (like setting up property injection) won’t work.
Autofac documentation - Controllers as services
您必须添加AddControllersAsServices
方法
public void ConfigureServices(IServiceCollection services)
{
services
.AddMvc()
.AddControllersAsServices();
}
就像 Steven 在评论中提到的那样,依靠中间件来拦截控制器的方法调用可能会更容易
and like Steven mentions on a comment it may be easier to rely on a middleware to intercept method call of controller
这篇关于使用Autofac在.NET Core 2.0 Web API控制器上进行拦截的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!