使用Autofac在.NET Core 2.0 Web API控制器上进行拦截 [英] Interception on .NET Core 2.0 Web API Controller By Using Autofac

查看:372
本文介绍了使用Autofac在.NET Core 2.0 Web API控制器上进行拦截的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图通过使用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, while EnableClassInterceptors() 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文档- 控制器即服务

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆