mirror of https://github.com/abpframework/abp.git
19 changed files with 386 additions and 115 deletions
@ -0,0 +1,14 @@ |
|||||
|
using Volo.Abp.Modularity.PlugIns; |
||||
|
|
||||
|
namespace Volo.Abp |
||||
|
{ |
||||
|
public class AbpApplicationOptions |
||||
|
{ |
||||
|
public PlugInSourceList PlugInSources { get; set; } |
||||
|
|
||||
|
public AbpApplicationOptions() |
||||
|
{ |
||||
|
PlugInSources = new PlugInSourceList(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,58 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using System.Reflection; |
||||
|
using Volo.ExtensionMethods.Collections.Generic; |
||||
|
|
||||
|
namespace Volo.Abp.Modularity |
||||
|
{ |
||||
|
public static class AbpModuleFinder |
||||
|
{ |
||||
|
public static List<Type> FindAllModuleTypes(Type startupModuleType) |
||||
|
{ |
||||
|
var moduleTypes = new List<Type>(); |
||||
|
AddModuleAndDependenciesResursively(moduleTypes, startupModuleType); |
||||
|
moduleTypes.AddIfNotContains(typeof(AbpKernelModule)); |
||||
|
return moduleTypes; |
||||
|
} |
||||
|
|
||||
|
public static List<Type> FindDependedModuleTypes(Type moduleType) |
||||
|
{ |
||||
|
AbpModule.CheckAbpModuleType(moduleType); |
||||
|
|
||||
|
var dependencies = new List<Type>(); |
||||
|
|
||||
|
var dependencyDescriptors = moduleType |
||||
|
.GetTypeInfo() |
||||
|
.GetCustomAttributes() |
||||
|
.OfType<IDependedModuleTypesProvider>(); |
||||
|
|
||||
|
foreach (var descriptor in dependencyDescriptors) |
||||
|
{ |
||||
|
foreach (var dependedModuleType in descriptor.GetDependedModuleTypes()) |
||||
|
{ |
||||
|
dependencies.AddIfNotContains(dependedModuleType); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return dependencies; |
||||
|
} |
||||
|
|
||||
|
private static void AddModuleAndDependenciesResursively(List<Type> moduleTypes, Type moduleType) |
||||
|
{ |
||||
|
AbpModule.CheckAbpModuleType(moduleType); |
||||
|
|
||||
|
if (moduleTypes.Contains(moduleType)) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
moduleTypes.Add(moduleType); |
||||
|
|
||||
|
foreach (var dependedModuleType in FindDependedModuleTypes(moduleType)) |
||||
|
{ |
||||
|
AddModuleAndDependenciesResursively(moduleTypes, dependedModuleType); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,47 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.IO; |
||||
|
using Volo.Abp.Reflection; |
||||
|
using Volo.ExtensionMethods.Collections.Generic; |
||||
|
|
||||
|
namespace Volo.Abp.Modularity.PlugIns |
||||
|
{ |
||||
|
public class FolderPlugInSource : IPlugInSource |
||||
|
{ |
||||
|
public string Folder { get; } |
||||
|
|
||||
|
public SearchOption SearchOption { get; set; } |
||||
|
|
||||
|
public FolderPlugInSource(string folder, SearchOption searchOption = SearchOption.TopDirectoryOnly) |
||||
|
{ |
||||
|
Folder = folder; |
||||
|
SearchOption = searchOption; |
||||
|
} |
||||
|
|
||||
|
public List<Type> GetModules() |
||||
|
{ |
||||
|
var modules = new List<Type>(); |
||||
|
|
||||
|
var assemblies = AssemblyHelper.GetAllAssembliesInFolder(Folder, SearchOption); |
||||
|
foreach (var assembly in assemblies) |
||||
|
{ |
||||
|
try |
||||
|
{ |
||||
|
foreach (var type in assembly.GetTypes()) |
||||
|
{ |
||||
|
if (AbpModule.IsAbpModule(type)) |
||||
|
{ |
||||
|
modules.AddIfNotContains(type); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
throw new AbpException("Could not get module types from assembly: " + assembly.FullName, ex); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return modules; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,10 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
|
||||
|
namespace Volo.Abp.Modularity.PlugIns |
||||
|
{ |
||||
|
public interface IPlugInSource |
||||
|
{ |
||||
|
List<Type> GetModules(); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,18 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
|
||||
|
namespace Volo.Abp.Modularity.PlugIns |
||||
|
{ |
||||
|
public static class PlugInSourceExtensions |
||||
|
{ |
||||
|
public static List<Type> GetModulesWithAllDependencies(this IPlugInSource plugInSource) |
||||
|
{ |
||||
|
return plugInSource |
||||
|
.GetModules() |
||||
|
.SelectMany(AbpModuleFinder.FindAllModuleTypes) |
||||
|
.Distinct() |
||||
|
.ToList(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,17 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
|
||||
|
namespace Volo.Abp.Modularity.PlugIns |
||||
|
{ |
||||
|
public class PlugInSourceList : List<IPlugInSource> |
||||
|
{ |
||||
|
internal List<Type> GetAllModules() |
||||
|
{ |
||||
|
return this |
||||
|
.SelectMany(pluginSource => pluginSource.GetModulesWithAllDependencies()) |
||||
|
.Distinct() |
||||
|
.ToList(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,18 @@ |
|||||
|
using System; |
||||
|
using System.IO; |
||||
|
|
||||
|
namespace Volo.Abp.Modularity.PlugIns |
||||
|
{ |
||||
|
public static class PlugInSourceListExtensions |
||||
|
{ |
||||
|
public static void AddFolder(this PlugInSourceList list, string folder, SearchOption searchOption = SearchOption.TopDirectoryOnly) |
||||
|
{ |
||||
|
list.Add(new FolderPlugInSource(folder, searchOption)); |
||||
|
} |
||||
|
|
||||
|
public static void AddTypes(this PlugInSourceList list, params Type[] moduleTypes) |
||||
|
{ |
||||
|
list.Add(new PlugInTypeListSource(moduleTypes)); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,21 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
|
||||
|
namespace Volo.Abp.Modularity.PlugIns |
||||
|
{ |
||||
|
public class PlugInTypeListSource : IPlugInSource |
||||
|
{ |
||||
|
private readonly Type[] _moduleTypes; |
||||
|
|
||||
|
public PlugInTypeListSource(params Type[] moduleTypes) |
||||
|
{ |
||||
|
_moduleTypes = moduleTypes; |
||||
|
} |
||||
|
|
||||
|
public List<Type> GetModules() |
||||
|
{ |
||||
|
return _moduleTypes.ToList(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,22 @@ |
|||||
|
using System.Collections.Generic; |
||||
|
using System.IO; |
||||
|
using System.Linq; |
||||
|
using System.Reflection; |
||||
|
using System.Runtime.Loader; |
||||
|
|
||||
|
namespace Volo.Abp.Reflection |
||||
|
{ |
||||
|
internal static class AssemblyHelper |
||||
|
{ |
||||
|
public static List<Assembly> GetAllAssembliesInFolder(string folderPath, SearchOption searchOption) |
||||
|
{ |
||||
|
var assemblyFiles = Directory |
||||
|
.EnumerateFiles(folderPath, "*.*", searchOption) |
||||
|
.Where(s => s.EndsWith(".dll") || s.EndsWith(".exe")); |
||||
|
|
||||
|
//TODO: AssemblyLoadContext not tested
|
||||
|
|
||||
|
return assemblyFiles.Select(AssemblyLoadContext.Default.LoadFromAssemblyPath).ToList(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,29 +0,0 @@ |
|||||
using Microsoft.Extensions.DependencyInjection; |
|
||||
using Shouldly; |
|
||||
using Volo.Abp; |
|
||||
using Volo.Abp.Modularity; |
|
||||
using Xunit; |
|
||||
|
|
||||
public class AbpApplication_Tests |
|
||||
{ |
|
||||
[Fact] |
|
||||
public void Should_Initialize_SingleModule_Application() |
|
||||
{ |
|
||||
//Arrange
|
|
||||
|
|
||||
var services = new ServiceCollection(); |
|
||||
|
|
||||
using (var application = AbpApplication.Create<IndependentEmptyModule>(services)) |
|
||||
{ |
|
||||
//Act
|
|
||||
|
|
||||
application.Initialize(services.BuildServiceProvider()); |
|
||||
|
|
||||
//Assert
|
|
||||
|
|
||||
var module = application.ServiceProvider.GetRequiredService<IndependentEmptyModule>(); |
|
||||
module.ConfigureServicesIsCalled.ShouldBeTrue(); |
|
||||
module.OnApplicationInitializeIsCalled.ShouldBeTrue(); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,56 @@ |
|||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using Shouldly; |
||||
|
using Volo.Abp.Modularity; |
||||
|
using Volo.Abp.Modularity.PlugIns; |
||||
|
using Xunit; |
||||
|
|
||||
|
namespace Volo.Abp |
||||
|
{ |
||||
|
public class AbpApplication_Initialize_Tests |
||||
|
{ |
||||
|
[Fact] |
||||
|
public void Should_Initialize_Single_Module() |
||||
|
{ |
||||
|
//Arrange
|
||||
|
|
||||
|
var services = new ServiceCollection(); |
||||
|
|
||||
|
using (var application = AbpApplication.Create<IndependentEmptyModule>(services)) |
||||
|
{ |
||||
|
//Act
|
||||
|
|
||||
|
application.Initialize(services.BuildServiceProvider()); |
||||
|
|
||||
|
//Assert
|
||||
|
|
||||
|
var module = application.ServiceProvider.GetRequiredService<IndependentEmptyModule>(); |
||||
|
module.ConfigureServicesIsCalled.ShouldBeTrue(); |
||||
|
module.OnApplicationInitializeIsCalled.ShouldBeTrue(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Should_Initialize_PlugIn() |
||||
|
{ |
||||
|
//Arrange
|
||||
|
|
||||
|
var services = new ServiceCollection(); |
||||
|
|
||||
|
using (var application = AbpApplication.Create<IndependentEmptyModule>(services, options => |
||||
|
{ |
||||
|
options.PlugInSources.AddTypes(typeof(IndependentEmptyPlugInModule)); |
||||
|
})) |
||||
|
{ |
||||
|
//Act
|
||||
|
|
||||
|
application.Initialize(services.BuildServiceProvider()); |
||||
|
|
||||
|
//Assert
|
||||
|
|
||||
|
var plugInModule = application.ServiceProvider.GetRequiredService<IndependentEmptyPlugInModule>(); |
||||
|
plugInModule.ConfigureServicesIsCalled.ShouldBeTrue(); |
||||
|
plugInModule.OnApplicationInitializeIsCalled.ShouldBeTrue(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,21 @@ |
|||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
|
||||
|
namespace Volo.Abp.Modularity |
||||
|
{ |
||||
|
public class IndependentEmptyPlugInModule : AbpModule |
||||
|
{ |
||||
|
public bool ConfigureServicesIsCalled { get; set; } |
||||
|
|
||||
|
public bool OnApplicationInitializeIsCalled { get; set; } |
||||
|
|
||||
|
public override void ConfigureServices(IServiceCollection services) |
||||
|
{ |
||||
|
ConfigureServicesIsCalled = true; |
||||
|
} |
||||
|
|
||||
|
public override void OnApplicationInitialization(ApplicationInitializationContext context) |
||||
|
{ |
||||
|
OnApplicationInitializeIsCalled = true; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue