Browse Source

Introduced module manager and revised module loader.

pull/81/head
Halil İbrahim Kalkan 10 years ago
parent
commit
0a6d557875
  1. 10
      src/Volo.Abp/Volo/Abp/AbpApplication.cs
  2. 5
      src/Volo.Abp/Volo/Abp/Modularity/IModuleLoader.cs
  3. 9
      src/Volo.Abp/Volo/Abp/Modularity/IModuleManager.cs
  4. 10
      src/Volo.Abp/Volo/Abp/Modularity/ModuleLifecycleManager.cs
  5. 50
      src/Volo.Abp/Volo/Abp/Modularity/ModuleLoader.cs
  6. 20
      src/Volo.Abp/Volo/Abp/Modularity/ModuleManager.cs
  7. 10
      test/Volo.Abp.Tests/Volo/Abp/Modularity/ModuleLoader_Tests.cs

10
src/Volo.Abp/Volo/Abp/AbpApplication.cs

@ -12,6 +12,8 @@ namespace Volo.Abp
public IServiceProvider ServiceProvider { get; private set; }
internal AbpModuleDescriptor[] Modules { get; }
private AbpApplication(
[NotNull] Type startupModuleType,
[NotNull] IServiceCollection services,
@ -26,7 +28,7 @@ namespace Volo.Abp
optionsAction?.Invoke(options);
services.AddCoreAbpServices(this);
LoadModules(services, options);
Modules = LoadModules(services, options);
}
internal static AbpApplication Create<TStartupModule>([NotNull] IServiceCollection services)
@ -66,11 +68,11 @@ namespace Volo.Abp
ServiceProvider.GetRequiredService<IModuleLifecycleManager>().InitializeModules();
}
private void LoadModules(IServiceCollection services, AbpApplicationCreationOptions options)
private AbpModuleDescriptor[] LoadModules(IServiceCollection services, AbpApplicationCreationOptions options)
{
services
return services
.GetSingletonInstance<IModuleLoader>()
.LoadAll(
.LoadModules(
services,
StartupModuleType,
options.PlugInSources

5
src/Volo.Abp/Volo/Abp/Modularity/IModuleLoader.cs

@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Modularity.PlugIns;
@ -7,8 +6,6 @@ namespace Volo.Abp.Modularity
{
public interface IModuleLoader
{
IReadOnlyList<AbpModuleDescriptor> Modules { get; }
void LoadAll(IServiceCollection services, Type startupModuleType, PlugInSourceList plugInSources);
AbpModuleDescriptor[] LoadModules(IServiceCollection services, Type startupModuleType, PlugInSourceList plugInSources);
}
}

9
src/Volo.Abp/Volo/Abp/Modularity/IModuleManager.cs

@ -0,0 +1,9 @@
using System.Collections.Generic;
namespace Volo.Abp.Modularity
{
public interface IModuleManager
{
IReadOnlyList<AbpModuleDescriptor> Modules { get; }
}
}

10
src/Volo.Abp/Volo/Abp/Modularity/ModuleLifecycleManager.cs

@ -5,12 +5,12 @@ namespace Volo.Abp.Modularity
{
public class ModuleLifecycleManager : IModuleLifecycleManager, ISingletonDependency
{
private readonly IModuleLoader _moduleLoader;
private readonly IModuleManager _moduleManager;
private readonly IEnumerable<IModuleLifecycleContributer> _contributers;
public ModuleLifecycleManager(IModuleLoader moduleLoader, IEnumerable<IModuleLifecycleContributer> contributers)
public ModuleLifecycleManager(IModuleManager moduleManager, IEnumerable<IModuleLifecycleContributer> contributers)
{
_moduleLoader = moduleLoader;
_moduleManager = moduleManager;
_contributers = contributers;
}
@ -18,7 +18,7 @@ namespace Volo.Abp.Modularity
{
foreach (var contributer in _contributers)
{
foreach (var module in _moduleLoader.Modules)
foreach (var module in _moduleManager.Modules)
{
contributer.Initialize(module.Instance);
}
@ -29,7 +29,7 @@ namespace Volo.Abp.Modularity
{
foreach (var contributer in _contributers)
{
foreach (var module in _moduleLoader.Modules)
foreach (var module in _moduleManager.Modules)
{
contributer.Shutdown(module.Instance);
}

50
src/Volo.Abp/Volo/Abp/Modularity/ModuleLoader.cs

@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Modularity.PlugIns;
@ -10,28 +9,19 @@ namespace Volo.Abp.Modularity
{
public class ModuleLoader : IModuleLoader
{
public IReadOnlyList<AbpModuleDescriptor> Modules => _modules.ToImmutableList();
private readonly List<AbpModuleDescriptor> _modules;
public ModuleLoader()
public AbpModuleDescriptor[] LoadModules(IServiceCollection services, Type startupModuleType, PlugInSourceList plugInSources)
{
_modules = new List<AbpModuleDescriptor>();
}
var modules = new List<AbpModuleDescriptor>();
public virtual void LoadAll(IServiceCollection services, Type startupModuleType, PlugInSourceList plugInSources)
{
if (_modules.Any())
{
throw new InvalidOperationException($"{nameof(LoadAll)} should be called only once!");
}
FillModules(modules, services, startupModuleType, plugInSources);
SetModuleDependencies(modules);
SortByDependency(modules, startupModuleType);
ConfigureServices(modules, services);
FillModules(services, startupModuleType, plugInSources);
SetModuleDependencies();
SortByDependency(startupModuleType);
ConfigureServices(services);
return modules.ToArray();
}
private void FillModules(IServiceCollection services, Type startupModuleType, PlugInSourceList plugInSources)
protected virtual void FillModules(List<AbpModuleDescriptor> modules, IServiceCollection services, Type startupModuleType, PlugInSourceList plugInSources)
{
//All modules starting from the startup module
var moduleTypes = AbpModuleFinder.FindAllModuleTypes(startupModuleType);
@ -45,23 +35,23 @@ namespace Volo.Abp.Modularity
//Create all modules
foreach (var moduleType in moduleTypes)
{
_modules.Add(CreateModuleDescriptor(services, moduleType));
modules.Add(CreateModuleDescriptor(services, moduleType));
}
}
private void SetModuleDependencies()
protected virtual void SetModuleDependencies(List<AbpModuleDescriptor> modules)
{
foreach (var module in Modules)
foreach (var module in modules)
{
SetModuleDependencies(module);
SetModuleDependencies(modules, module);
}
}
private void SortByDependency(Type startupModuleType)
protected virtual void SortByDependency(List<AbpModuleDescriptor> modules, Type startupModuleType)
{
_modules.SortByDependencies(m => m.Dependencies);
_modules.MoveItem(m => m.Type == typeof(AbpKernelModule), 0);
_modules.MoveItem(m => m.Type == startupModuleType, _modules.Count - 1);
modules.SortByDependencies(m => m.Dependencies);
modules.MoveItem(m => m.Type == typeof(AbpKernelModule), 0);
modules.MoveItem(m => m.Type == startupModuleType, modules.Count - 1);
}
protected virtual AbpModuleDescriptor CreateModuleDescriptor(IServiceCollection services, Type moduleType)
@ -76,19 +66,19 @@ namespace Volo.Abp.Modularity
return module;
}
protected virtual void ConfigureServices(IServiceCollection services)
protected virtual void ConfigureServices(List<AbpModuleDescriptor> modules, IServiceCollection services)
{
foreach (var module in _modules)
foreach (var module in modules)
{
module.Instance.ConfigureServices(services);
}
}
protected virtual void SetModuleDependencies(AbpModuleDescriptor module)
protected virtual void SetModuleDependencies(List<AbpModuleDescriptor> modules, AbpModuleDescriptor module)
{
foreach (var dependedModuleType in AbpModuleFinder.FindDependedModuleTypes(module.Type))
{
var dependedModule = _modules.FirstOrDefault(m => m.Type == dependedModuleType);
var dependedModule = modules.FirstOrDefault(m => m.Type == dependedModuleType);
if (dependedModule == null)
{
throw new AbpException("Could not find a depended module " + dependedModuleType.AssemblyQualifiedName + " for " + module.Type.AssemblyQualifiedName);

20
src/Volo.Abp/Volo/Abp/Modularity/ModuleManager.cs

@ -0,0 +1,20 @@
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using Volo.DependencyInjection;
namespace Volo.Abp.Modularity
{
public class ModuleManager : IModuleManager, ISingletonDependency
{
public IReadOnlyList<AbpModuleDescriptor> Modules => _modules.ToImmutableList();
private readonly List<AbpModuleDescriptor> _modules;
public ModuleManager(AbpApplication application)
{
_modules = application.Modules.ToList();
}
}
}

10
test/Volo.Abp.Tests/Volo/Abp/Modularity/ModuleLoader_Tests.cs

@ -11,11 +11,11 @@ namespace Volo.Abp.Modularity
public void Should_Load_Modules_By_Dependency_Order()
{
var moduleLoader = new ModuleLoader();
moduleLoader.LoadAll(new ServiceCollection(), typeof(MyStartupModule), new PlugInSourceList());
moduleLoader.Modules.Count.ShouldBe(3);
moduleLoader.Modules[0].Type.ShouldBe(typeof(AbpKernelModule));
moduleLoader.Modules[1].Type.ShouldBe(typeof(IndependentEmptyModule));
moduleLoader.Modules[2].Type.ShouldBe(typeof(MyStartupModule));
var modules = moduleLoader.LoadModules(new ServiceCollection(), typeof(MyStartupModule), new PlugInSourceList());
modules.Length.ShouldBe(3);
modules[0].Type.ShouldBe(typeof(AbpKernelModule));
modules[1].Type.ShouldBe(typeof(IndependentEmptyModule));
modules[2].Type.ShouldBe(typeof(MyStartupModule));
}
[DependsOn(typeof(IndependentEmptyModule))]

Loading…
Cancel
Save