如何在 asp.net 核 webapi 中使用 Unity 容器拦截



如果我尝试在 asp.net 核 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>()

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

有关我用于测试目的的 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核心控制台应用程序,我甚至可以成功地使用以下扩展名自动配置每个注册类型以进行拦截。

/// <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解析服务。

我不确定这是问题的答案。 据我了解,最初的问题是没有创建必须拦截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方法。我希望这能给你一些想法或有助于使工作成为你的拦截行为。

最新更新