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);