你的位置:首页 > ASP.net教程

[ASP.net教程]ABP框架详解(二)AbpKernelModule


  AbpKernelModule类是Abp框架自己的Module,它也跟所有其他的Module一样继承自AbpModule,重写PreInitialize,Initialize,PostInitialize三个主要成员,在所有Module的基类AbpModule中已经拥有了IIocManager和IAbpStartupConfiguration的受保护的成员,所以后面所有的Module都可以直接获取并使用相关的功能,AbpModule同时提供了两个非常有用的公有静态方法public static bool IsAbpModule(Type type)和public static List<Type> FindDependedModuleTypes(Type moduleType),顾名思义第一个方法用于判断一个类型是否是Module类型,另一个用于根据指定的类型查找器所有依赖的Module。

  1. PreInitialize()方法,方法内第一步是约定需要被注册的类型
    IocManager.AddConventionalRegistrar(new BasicConventionalRegistrar());

     BasicConventionalRegistrar继承自IConventionalDependencyRegistrar,在RegisterAssembly方法体中注册所有ITransientDependency,ISingletonDependency,IInterceptor的实现类,这是非常有用的,在后面自己的应用程序或者其他程序集中就可以只需要实现上面三个接口,无需再做任何事情,就会被注册到依赖容器中,使用的时候直接Resolve就可以使用了,实现类以单例模式被注册或者瞬态方式被注册。如果被注册的类直接或者间接实现IInitializable接口那么在第一次被实例化的时候同时会被初始化。

   在Castle的依赖容器中每一个类型被注册的时候都会触发IWindsorContainer.Kernel.ComponentRegistered委托,所以就可以在写一   些逻辑判断当前被注册的类是否满足条件,决定是否需要为注册类添加拦截器实现AOP。

   (1)ValidationInterceptorRegistrar就是用来实现以上功能的一个实践,从名称上可以看出该类是用来注册验证拦截器的,这是一    个静态类  他们通常会定义一个公共静态的Initialize(IIocManager iocManager)方法来被调用,默认是为所有    IApplicationService的实现类添加ValidationInterceptor拦截器,拦截器的内部会new一个MethodInvocationValidator的新实例调用该实例的Validate()方法,构造函数传递IApplicationService被调用方法的MethodInfo和参数值,如果MethodInfo是非公有,或者应用了DisableValidationAttribute,还有参数值为空的话就不做任何验证,将被验证的参数必须继承IValidate否则整个验证就结束,可以实现ICustomValidate,系统会进行执行验证,同时应用了ValidationAttribute的话也会被执行,所有产生的错误会被添加到一个结果集合中,如果验证结果集合中存在项就会抛异常,最后验证ok,所有实现了IShouldNormalize的参数会被执行Normalize()方法。

   (2)FeatureInterceptorRegistrar是为所有被注册到依赖容器中应用了RequiresFeatureAttribute或者其任意方法应用了该特性的类添加FeatureInterceptor拦截器,收集方法和类上定义的所有RequiresFeatureAttribute,调用依赖容器中的IFeatureChecker迭代调用RequiresFeatureAttribute,确保方法是否可用。

private void CheckFeatures(IEnumerable<RequiresFeatureAttribute> featureAttributes)    {      _iocResolver.Using<IFeatureChecker>(featureChecker =>      {        foreach (var featureAttribute in featureAttributes)        {          featureChecker.CheckEnabled(featureAttribute.RequiresAll, featureAttribute.Features);        }      });    }

   (3)AuditingInterceptorRegistrar用于决定方法的执行是否需要被审计记录,从容器中获取IAuditingConfiguration如果IsEnabled为true,被注册的类满足IAuditingConfiguration的Selectors中任意一个Predicate委托,或者类或者当前MethodTarget上应用了AuditedAttribute就执行审计记录,也即添加AuditingInterceptor拦截器,收集被调用方法的名称参数调用时间,执行持续时间,执行人等等信息,使用IAuditingStore执行持久化操作。

  (4)UnitOfWorkRegistrar通过判断被执行的类或方法是否需要包含在一个事务中被执行,默认IRepository和IApplicationService是需要被事务执行的当然任意方法应用了UnitOfWorkAttribute也会被当做事务实行,事务的实现机制以AOP的形式封装在UnitOfWorkInterceptor中,在拦截器执行的时候会优先判断当前线程槽中是否已经保存了一个事务GUID(通过GUID可以在事务的一个静态字典中找到相应的IActiveUnitOfWork)并且没有执行过Dispose,如果以上条件满足就什么也不做(继续应用调用者的事务上下文),否则获取应用的UnitOfWorkAttribute特性(必须不为空并且IsDisabled属性为false)或者new一个默认的UnitOfWorkAttribute,使用此特性创建UnitOfWorkOptions开启一个新的上下文执行环境_unitOfWorkManager.Begin(options),执行完毕后通过单元工作完成句柄释放相关事务上下文。

  (5)AuthorizationInterceptorRegistrar为IApplicationService的应用服务层的调用进行权限验证拦截器,如果需要真正执行权限验证的话还需要为IApplicationService的类或者方法应用AbpAuthorizeAttribute特性,依赖容器解析出一个IAuthorizeAttributeHelper的实例,递归调用AbpAuthorizeAttribute实例,判断是否具有权限执行IApplicationService的方法

  (6)为IApplicationServeice的实现类添加审计功能

Configuration.Auditing.Selectors.Add(        new NamedTypeSelector(          "Abp.ApplicationServices",          type => typeof(IApplicationService).IsAssignableFrom(type)          )        );

  (7)添加系统默认Setting,以及为UnitOfWork中所有数据库访问添加默认过滤机制

Configuration.Settings.Providers.Add<LocalizationSettingProvider>();      Configuration.Settings.Providers.Add<EmailSettingProvider>();            Configuration.UnitOfWork.RegisterFilter(AbpDataFilters.SoftDelete, true);      Configuration.UnitOfWork.RegisterFilter(AbpDataFilters.MustHaveTenant, true);      Configuration.UnitOfWork.RegisterFilter(AbpDataFilters.MayHaveTenant, true);

  (8)ConfigureCaches()方法为三种不同级别的缓存设置不同的SlidingExpireTime,系统级的为8小时,租户级的为1小时,某个用户级的为20分钟

Configuration.Caching.Configure(AbpCacheNames.ApplicationSettings, cache =>      {        cache.DefaultSlidingExpireTime = TimeSpan.FromHours(8);      });      Configuration.Caching.Configure(AbpCacheNames.TenantSettings, cache =>      {        cache.DefaultSlidingExpireTime = TimeSpan.FromMinutes(60);      });      Configuration.Caching.Configure(AbpCacheNames.UserSettings, cache =>      {        cache.DefaultSlidingExpireTime = TimeSpan.FromMinutes(20);      });

  1. Initialize()方法,同很多其他的Web开发框架一样,Abp也提供了自己的EventBus事件处理机制,在Abp的Module的Initialize()方法中注册EventBusInstaller : IWindsorInstaller,Install方法会优先判断IEventBusConfiguration.UseDefaultEventBus是否为true,如果是就注册一个默认的静态的EventBus实例,否则注册一个新的EventBus,为所有即将注册到依赖容器中并且实现了IEventHandler接口的类封装成一个IocHandlerFactory,注册到EventBus中(拿到的所有即将被注册的IEventHandler的实现类获取具有一个泛型参数的子接口,该泛型参数就是事件类型将作为key注册到EventBus中)。
  2. 传递Abp的程序集作为参数执行IocManager所有约定注册机。完成相关类型的自动注册到容器中(不要注册Abp中IWindsorInstaller的实现类)。
  3. PostInitialize()方法,为一些缺省的类型注册默认Null实现类
    IocManager.RegisterIfNot<IUnitOfWork, NullUnitOfWork>(DependencyLifeStyle.Transient);      IocManager.RegisterIfNot<IAuditInfoProvider, NullAuditInfoProvider>(DependencyLifeStyle.Singleton);      IocManager.RegisterIfNot<IAuditingStore, SimpleLogAuditingStore>(DependencyLifeStyle.Transient);      IocManager.RegisterIfNot<ITenantIdResolver, NullTenantIdResolver>(DependencyLifeStyle.Singleton);      IocManager.RegisterIfNot<IAbpSession, ClaimsAbpSession>(DependencyLifeStyle.Singleton);    

     

  4. 解析并初始化相关管理类
    IocManager.Resolve<SettingDefinitionManager>().Initialize();      IocManager.Resolve<FeatureManager>().Initialize();      IocManager.Resolve<NavigationManager>().Initialize();      IocManager.Resolve<PermissionManager>().Initialize();      IocManager.Resolve<LocalizationManager>().Initialize();