using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using Abp.Collections.Extensions; using Abp.Configuration.Startup; using Abp.Dependency; using Castle.Core.Logging; namespace Abp.Modules { /// /// This class must be implemented by all module definition classes. /// /// /// A module definition class is generally located in its own assembly /// and implements some action in module events on application startup and shutdown. /// It also defines depended modules. /// public abstract class AbpModule { /// /// Gets a reference to the IOC manager. /// protected internal IIocManager IocManager { get; internal set; } /// /// Gets a reference to the ABP configuration. /// protected internal IAbpStartupConfiguration Configuration { get; internal set; } /// /// Gets or sets the logger. /// public ILogger Logger { get; set; } protected AbpModule() { Logger = NullLogger.Instance; } /// /// This is the first event called on application startup. /// Codes can be placed here to run before dependency injection registrations. /// public virtual void PreInitialize() { } /// /// This method is used to register dependencies for this module. /// public virtual void Initialize() { } /// /// This method is called lastly on application startup. /// public virtual void PostInitialize() { } /// /// This method is called when the application is being shutdown. /// public virtual void Shutdown() { } public virtual Assembly[] GetAdditionalAssemblies() { return new Assembly[0]; } /// /// Checks if given type is an Abp module class. /// /// Type to check public static bool IsAbpModule(Type type) { var typeInfo = type.GetTypeInfo(); return typeInfo.IsClass && !typeInfo.IsAbstract && !typeInfo.IsGenericType && typeof(AbpModule).IsAssignableFrom(type); } /// /// Finds direct depended modules of a module (excluding given module). /// public static List FindDependedModuleTypes(Type moduleType) { if (!IsAbpModule(moduleType)) { throw new AbpInitializationException("This type is not an ABP module: " + moduleType.AssemblyQualifiedName); } var list = new List(); if (moduleType.GetTypeInfo().IsDefined(typeof(DependsOnAttribute), true)) { var dependsOnAttributes = moduleType.GetTypeInfo().GetCustomAttributes(typeof(DependsOnAttribute), true).Cast(); foreach (var dependsOnAttribute in dependsOnAttributes) { foreach (var dependedModuleType in dependsOnAttribute.DependedModuleTypes) { list.Add(dependedModuleType); } } } return list; } public static List FindDependedModuleTypesRecursivelyIncludingGivenModule(Type moduleType) { var list = new List(); AddModuleAndDependenciesRecursively(list, moduleType); list.AddIfNotContains(typeof(AbpKernelModule)); return list; } private static void AddModuleAndDependenciesRecursively(List modules, Type module) { if (!IsAbpModule(module)) { throw new AbpInitializationException("This type is not an ABP module: " + module.AssemblyQualifiedName); } if (modules.Contains(module)) { return; } modules.Add(module); var dependedModules = FindDependedModuleTypes(module); foreach (var dependedModule in dependedModules) { AddModuleAndDependenciesRecursively(modules, dependedModule); } } } }