注册相同的Unity拦截&;所有注册类型的调用处理程序

本文关键字:注册 程序 类型 调用 处理 amp Unity 拦截 | 更新日期: 2023-09-27 18:21:39

我有一个ICallHandler,我想在我的所有Unity容器实例中注册它。

例如,以以下处理程序为例:

public class ProfilerHandler : ICallHandler
{
    public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
    {
        //start timer
        IMethodReturn methodReturn = getNext()(input, getNext);
        //stop timer
    }
    public int Order
    {
        get; set;
    }
}

以及以下IoC容器构造函数:

public class IoCContainer : UnityContainer
{
    public IoCContainer()
    {
        this.RegisterType<IUserService, UserService>(new ContainerControlledLifetimeManager());
        this.RegisterType<IRepository<User>, UserRepository>(new ContainerControlledLifetimeManager());
    }
}

我只想用所有这些类型注册这个处理程序。

我可以用一些非常冗长的代码来完成这项工作:

public class IoCContainer : UnityContainer
{
    public IoCContainer()
    {
        this.AddNewExtension<Interception>();
        this.RegisterType<IUserService, UserService>(new ContainerControlledLifetimeManager()).Configure<Interception>().SetInterceptorFor<IUserService>(new InterfaceInterceptor());
        this.RegisterType<IRepository<User>, UserRepository>(new ContainerControlledLifetimeManager()).Configure<Interception>().SetInterceptorFor<IRepository<User>>(new InterfaceInterceptor());
    }
}

但是,我不仅必须在我的所有类型注册上写相同的拦截代码(想象一下,如果我有100多个类型注册),而且我还必须在每个接口上包含一个HandlerAttribute(同样,如果我要将其应用于100多个接口,那就不好了)。

这是我唯一的选择吗?或者有没有一种方法可以在容器级别做到这一点,以避免将其应用于每个单独的类型注册&界面

注册相同的Unity拦截&;所有注册类型的调用处理程序

Unity 3通过约定提供注册,在这种情况下可能会有所帮助:

IUnityContainer container = new UnityContainer();
container.AddNewExtension<Interception>();
container.RegisterTypes(
    AllClasses.FromLoadedAssemblies().Where(
        t => t.Namespace == "My.Namespace.Services"),
    WithMappings.MatchingInterface,
    getInjectionMembers: t => new InjectionMember[]
    {
        new Interceptor<InterfaceInterceptor>(),
        new InterceptionBehavior<MyBehavior>()
    });
}

您可以将以上内容与策略注入相结合,使用匹配规则来连接您的调用处理程序。这样,您就可以使用各种匹配规则来代替(或与)属性来确定哪些调用处理程序与哪些类/方法一起使用。

container.RegisterTypes(
    AllClasses.FromLoadedAssemblies().Where(
        t => t.Namespace == "My.Namespace.Services"),
    WithMappings.MatchingInterface,
    getInjectionMembers: t => new InjectionMember[]
    {
        new InterceptionBehavior<PolicyInjectionBehavior>(),
        new Interceptor<InterfaceInterceptor>(),
    });
}
container.Configure<Interception>()
    .AddPolicy("profiler")
    .AddMatchingRule<AssemblyMatchingRule>(
        new InjectionConstructor(
            new InjectionParameter("My.Namespace.Services")))
    .AddCallHandler<ProfilerHandler>(
        new ContainerControlledLifetimeManager());

Unity 2还支持政策注入。

按照惯例进行注册的另一种选择是编写一个Unity Container Extension,以在注册期间执行拦截的连接。