注册相同的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 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,以在注册期间执行拦截的连接。