简体   繁体   English

使用Autofac在.NET Core 2.0 Web API控制器上进行拦截

[英]Interception on .NET Core 2.0 Web API Controller By Using Autofac

I am trying to use interceptions on .Net Core 2.0 WebApi Application by using Autofac but I couldnt succeed it on Controllers. 我试图通过使用Autofac在.Net Core 2.0 WebApi应用程序上使用侦听,但是我无法在Controller上成功接管。 What I try is 我尝试的是

First I created a basic webapi which has one default controller(ValuesController). 首先,我创建了一个基本的webapi,它具有一个默认控制器(ValuesController)。 Then I set up the autofac configuration as below. 然后,我按如下所示设置autofac配置。 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 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 使用类型拦截时,方法应声明为虚拟

Under the covers, EnableInterfaceInterceptors() creates an interface proxy that performs the interception, while EnableClassInterceptors() dynamically subclasses the target component to perform interception of virtual methods. EnableInterfaceInterceptors()EnableInterfaceInterceptors()创建执行拦截的接口代理,而EnableClassInterceptors()动态子类化目标组件以执行虚拟方法的拦截。
Autofac documentation - Enable interception on types Autofac文档-启用类型拦截

ie : 即:

// GET api/values
[HttpGet]
public virtual IEnumerable<string> Get()
{
    return new string[] { "value1", "value2" };
}

BTW you are trying to intercept method of ASP.net core controller. 顺便说一句,您正在尝试拦截ASP.net核心控制器的方法。 In this case controllers are not resolved by Autofac by default 在这种情况下,默认情况下Autofac无法解析控制器

By default, ASP.NET Core will resolve the controller parameters from the container but doesn't actually resolve the controller from the container. 默认情况下,ASP.NET Core将从容器中解析控制器参数,但实际上不会从容器中解析控制器。 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 Autofac文档-控制器即服务

you have to add the AddControllersAsServices method 您必须添加AddControllersAsServices方法

public void ConfigureServices(IServiceCollection services)
{
    services
        .AddMvc()
        .AddControllersAsServices();
}

and like Steven mentions on a comment it may be easier to rely on a middleware to intercept method call of controller 就像史蒂文(Steven )在评论中提到的那样,依靠中间件来拦截控制器的方法调用可能会更容易

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM