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