UNITY v.3 - 使用命名空间匹配的BehaviorInterception

时间:2015-04-19 12:14:44

标签: unity-container aop enterprise-library

如何将行为应用于特定命名空间中的所有接口? 我知道如何将行为应用到像IMyBlFacade这样的具体界面, 但是我不想单独为所有界面做这件事,而是一次性。

使用自定义IInterfaceBehaviors时,实现ICallHandler是否已过时? 据我所知,两者都构建了拦截管道。

在IInterfacebehaviors上使用ootb callhandler和自定义callhandler有什么好处?

我不希望它像这样:

unity.RegisterType<IMyService, MyService>(
new ContainerControlledLifetimeManager(), 
new Interceptor<InterfaceInterceptor>(), 
new InterceptionBehavior<OutputInterceptionBehavior>());

更喜欢这个(伪代码):

unity.addInterceptor<InterfaceInterceptor>()
.addMachingRule<namespace>("mynamespace")
.addBehaviors(...);

1 个答案:

答案 0 :(得分:0)

所以使用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);