【问题标题】:How to use unity-container interception in asp.net-core webapi如何在asp.net-core webapi中使用unity-container拦截
【发布时间】:2018-11-14 21:20:25
【问题描述】:

如果我尝试在 asp.net-core webapi 中使用统一拦截,我的调用处理程序将永远不会被调用。我知道它适用于 .net-core 控制台应用程序、非核心应用程序,甚至是同一个项目中没有 webapi 东西的测试(从测试容器解析服务)。

这是我用来设置 api 的(相关)代码:

Program.cs:

.UseUnityServiceProvider()

Startup.cs

public void ConfigureContainer(IUnityContainer container) {
    container.AddNewExtension<Interception>();
    container.RegisterType<IProjectService, ProjectService>().Configure<Interception>().SetInterceptorFor<IProjectService>(new InterfaceInterceptor());
}

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

我怀疑这与UseUnityServiceProvider() 设置的Unity.Microsoft.DependencyInjection.ServiceProvider 以一种不拦截的方式解析类型有关。

那么我需要做些什么才能让拦截正常工作?或者这是某个地方的已知错误?

[更新]

@Albert:你的意思是这样的吗:

container.RegisterType<IProjectService, ProjectService>(new InterceptionBehavior<PolicyInjectionBehavior>()); // new Interceptor<InterfaceInterceptor>()

即使我将 InterfaceInterceptor 添加为第二个参数,它也不会改变任何东西。

关于我用于测试目的的 HandlerAttribute 和 CallHandler 的更多信息:

public class DummyLoggingAttribute : HandlerAttribute {
    public override ICallHandler CreateHandler(IUnityContainer container) 
        return new DummyLoggerCallHandler(){Order = 2};
    }
}

public class DummyLoggerCallHandler : ICallHandler{
    private int _order;

    public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext) {
        Console.WriteLine("log vor ");

        IMethodReturn result = getNext()(input, getNext);

        Console.WriteLine("log danach ");
        return result;
    }

    public int Order {
        get { return _order; }
        set { _order = value; }
    }
}

应用于如下方法。

[DummyLogging]
public virtual IList<Project> GetAllProjects() {
    return _projectDao.GetAll();
}

如果我将属性添加到接口、实现或两者中,它甚至没有任何区别。

我是另一个 .net-core 控制台应用程序,我什至可以成功使用以下扩展来自动配置每个注册类型以进行拦截。

/// <summary>
///     Extension für das automatische Intercepten von Methoden
/// </summary>
public class InterceptionExtension : UnityContainerExtension {
    /// <summary>
    ///     Entfernt die Extension
    /// </summary>
    public override void Remove() {
        Context.Registering -= OnRegister;
        Context.RegisteringInstance -= OnRegisterInstance;
    }

    /// <summary>
    ///     Initialisiert die Extension
    /// </summary>
    protected override void Initialize() {
        Container.AddNewExtension<Interception>();

        Context.Registering += OnRegister;
        Context.RegisteringInstance += OnRegisterInstance;
    }

    /// <summary>
    ///     Event wenn ein Type Registriert wird
    /// </summary>
    private void OnRegister(object sender, RegisterEventArgs e) {
        if (e.TypeFrom != null) {
            Container.Configure<Interception>()
                    .SetInterceptorFor(e.TypeFrom, new InterfaceInterceptor());
        }
    }

    /// <summary>
    ///     Event wenn eine Instance Regestriert wird
    /// </summary>
    private void OnRegisterInstance(object sender, RegisterInstanceEventArgs e) {
        Container.Configure<Interception>()
                .SetInterceptorFor(e.RegisteredType, new InterfaceInterceptor());
    }
}

这让我假设注册拦截不是问题,而是通过UnityServiceProvider解析服务。

【问题讨论】:

  • 据我了解,您需要指定IInterceptionBehavior。你会吗?

标签: c# asp.net-core unity-container asp.net-core-2.0 asp.net-core-webapi


【解决方案1】:

我不确定这是否是问题的答案。 据我了解,最初的问题是没有创建必须拦截ProjectService 的方法调用的代理类。 我可以通过创建一个派生自 IInterceptionBehavior 的类和稍微不同的类型注册来修复它。

我的拦截行为:

public class MyInterceptionBehavior : IInterceptionBehavior
{
    public bool WillExecute
    {
        get { return true; }
    }

    public IEnumerable<Type> GetRequiredInterfaces()
    {
        return Enumerable.Empty<Type>();
    }

    public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
    {
        IMethodReturn result = getNext()(input, getNext);
        Console.WriteLine("Interception Called");
        return result;
    }

}

ConfigureContainer() 中,将您的IProjectService 注册替换为:

container.RegisterType<IProjectService, ProjectService>(
    new Interceptor<InterfaceInterceptor>(),
    new InterceptionBehavior<MyInterceptionBehavior>());

IProjectService 的每个方法被调用时,每次调用Invoke 方法。我希望这会给你一些想法或帮助你拦截行为。

【讨论】:

  • 对不起,先生,但这让事情变得更糟。现在,即使之前运行没有问题的文本案例也忽略了拦截。测试用例和web api的区别:-web api使用服务提供者获取服务的实例-测试用例直接调用container.Resolve&lt;IProjectService&gt;()
  • @debgz,您是否尝试将 MyInterceptionBehavior 替换为 PolicyInjectionBehavior
  • 是的,以前试过。但它不会改变任何东西。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-17
  • 1970-01-01
  • 2018-09-07
  • 2017-10-09
相关资源
最近更新 更多