UNITY v.3 - 使用命名空间匹配的 BehaviorInterception
UNITY v.3 - BehaviorInterception using namespace matching
如何将行为应用于特定命名空间中的所有接口?
我知道如何将行为应用到像 IMyBlFacade 这样的具体界面,
但我不想对所有接口分别执行此操作,而是一次完成。
使用自定义 IInterfaceBehaviors 时实现 ICallHandler 是否过时?
据我了解,两者都建立了拦截管道。
与 IInterfacebehaviors 相比,使用 ootb 调用处理程序和自定义调用处理程序有什么好处?
我不想这样:
unity.RegisterType<IMyService, MyService>(
new ContainerControlledLifetimeManager(),
new Interceptor<InterfaceInterceptor>(),
new InterceptionBehavior<OutputInterceptionBehavior>());
像这样(伪代码):
unity.addInterceptor<InterfaceInterceptor>()
.addMachingRule<namespace>("mynamespace")
.addBehaviors(...);
所以使用Unity的RegistrationByConvention是部分可行的。
据我了解,你只能做简单的映射。
对于更复杂的映射,例如使用各种 InjectionMembers,您必须手动映射它们。
您必须继承 RegistrationConvention 才能构建您自己的约定实现。
public class UnityRegistrationByConventions : RegistrationConvention
{
private readonly IUnityContainer _container;
List<string> _assemblyNameFilter;
List<string> _namespaceFilterForClasses;
public UnityRegistrationByConventions(IUnityContainer container, List<string> assemblyNameFilter = null, List<string> namespaceFilterForClasses = null)
{
_container = container;
_assemblyNameFilter = assemblyNameFilter;
_namespaceFilterForClasses = namespaceFilterForClasses;
}
public override Func<Type, IEnumerable<Type>> GetFromTypes()
{
return WithMappings.FromMatchingInterface;
}
public override Func<Type, IEnumerable<InjectionMember>> GetInjectionMembers()
{
return (t => new List<InjectionMember>(){
new Interceptor<InterfaceInterceptor>(),
new InterceptionBehavior<LoggingInterceptionBehavior>(), // 1
new InterceptionBehavior<ExceptionInterceptionBehavior>(), // 2
new InterceptionBehavior<CachingInterceptionBehavior>(), // 3
new InterceptionBehavior<ValidationInterceptionBehavior>()} as IEnumerable<InjectionMember>);
}
public override Func<Type, LifetimeManager> GetLifetimeManager()
{
return t => WithLifetime.Transient(t);
}
public override Func<Type, string> GetName()
{
return (type => (this._container.Registrations.Select(x => x.RegisteredType)
.Any(r => type.GetInterfaces().Contains(r) == true) == true) ? WithName.TypeName(type) : WithName.Default(type));
}
public override IEnumerable<Type> GetTypes()
{
var allAssemblies = AppDomain.CurrentDomain.GetAssemblies().Where(a => _assemblyNameFilter.Contains(a.FullName.Split(',')[0]));
List<Type> allClasses = new List<Type>();
foreach (var assembly in allAssemblies)
{
var classArray = assembly.GetTypes().Where(t => t.IsPublic &&
!t.IsAbstract &&
t.IsClass == true &&
_namespaceFilterForClasses.Contains(t.Namespace));
if (classArray != null && classArray.Count() > 0)
allClasses.AddRange(classArray);
}
return allClasses;
}
}
并像这样应用约定
var rby = new UnityRegistrationByConventions(unityContainer, assFilter, classNamespaceFilter);
如何将行为应用于特定命名空间中的所有接口? 我知道如何将行为应用到像 IMyBlFacade 这样的具体界面, 但我不想对所有接口分别执行此操作,而是一次完成。
使用自定义 IInterfaceBehaviors 时实现 ICallHandler 是否过时? 据我了解,两者都建立了拦截管道。
与 IInterfacebehaviors 相比,使用 ootb 调用处理程序和自定义调用处理程序有什么好处?
我不想这样:
unity.RegisterType<IMyService, MyService>(
new ContainerControlledLifetimeManager(),
new Interceptor<InterfaceInterceptor>(),
new InterceptionBehavior<OutputInterceptionBehavior>());
像这样(伪代码):
unity.addInterceptor<InterfaceInterceptor>()
.addMachingRule<namespace>("mynamespace")
.addBehaviors(...);
所以使用Unity的RegistrationByConvention是部分可行的。 据我了解,你只能做简单的映射。
对于更复杂的映射,例如使用各种 InjectionMembers,您必须手动映射它们。
您必须继承 RegistrationConvention 才能构建您自己的约定实现。
public class UnityRegistrationByConventions : RegistrationConvention
{
private readonly IUnityContainer _container;
List<string> _assemblyNameFilter;
List<string> _namespaceFilterForClasses;
public UnityRegistrationByConventions(IUnityContainer container, List<string> assemblyNameFilter = null, List<string> namespaceFilterForClasses = null)
{
_container = container;
_assemblyNameFilter = assemblyNameFilter;
_namespaceFilterForClasses = namespaceFilterForClasses;
}
public override Func<Type, IEnumerable<Type>> GetFromTypes()
{
return WithMappings.FromMatchingInterface;
}
public override Func<Type, IEnumerable<InjectionMember>> GetInjectionMembers()
{
return (t => new List<InjectionMember>(){
new Interceptor<InterfaceInterceptor>(),
new InterceptionBehavior<LoggingInterceptionBehavior>(), // 1
new InterceptionBehavior<ExceptionInterceptionBehavior>(), // 2
new InterceptionBehavior<CachingInterceptionBehavior>(), // 3
new InterceptionBehavior<ValidationInterceptionBehavior>()} as IEnumerable<InjectionMember>);
}
public override Func<Type, LifetimeManager> GetLifetimeManager()
{
return t => WithLifetime.Transient(t);
}
public override Func<Type, string> GetName()
{
return (type => (this._container.Registrations.Select(x => x.RegisteredType)
.Any(r => type.GetInterfaces().Contains(r) == true) == true) ? WithName.TypeName(type) : WithName.Default(type));
}
public override IEnumerable<Type> GetTypes()
{
var allAssemblies = AppDomain.CurrentDomain.GetAssemblies().Where(a => _assemblyNameFilter.Contains(a.FullName.Split(',')[0]));
List<Type> allClasses = new List<Type>();
foreach (var assembly in allAssemblies)
{
var classArray = assembly.GetTypes().Where(t => t.IsPublic &&
!t.IsAbstract &&
t.IsClass == true &&
_namespaceFilterForClasses.Contains(t.Namespace));
if (classArray != null && classArray.Count() > 0)
allClasses.AddRange(classArray);
}
return allClasses;
}
}
并像这样应用约定
var rby = new UnityRegistrationByConventions(unityContainer, assFilter, classNamespaceFilter);