You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

96 lines
3.3 KiB
C#

1 year ago
using DS.Module.Core.Extensions;
using DS.Module.Core.Reflection;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using System.Linq.Expressions;
namespace DS.Module.Core.Modules;
public class ModuleApplicationBase : IModuleApplication
{
public Type StartupModuleType { get; set; }
public IServiceCollection Services { get; set; }
public IServiceProvider ServiceProvider { get; set; }
/// <summary>
/// 模块接口容器
/// </summary>
public IReadOnlyList<IDSAppModule> Modules { get; set; }
public List<IDSAppModule> Source { get; protected set; }
public ModuleApplicationBase(Type startupModuleType, IServiceCollection services)
{
StartupModuleType = startupModuleType;
Services = services;
services.TryAddSingleton<IAssemblyFinder, AssemblyFinder>();
services.TryAddSingleton<ITypeFinder, TypeFinder>();
services.AddSingleton<IModuleApplication>(this);
services.TryAddObjectAccessor<IServiceProvider>();
Source = this.GetAllModule(services);
Modules = this.LoadModules();
}
protected virtual List<IDSAppModule> GetAllModule(IServiceCollection services)
{
var typeFinder = services.GetOrAddSingletonService<ITypeFinder, TypeFinder>();
var typs = typeFinder.Find(o => DSAppModule.IsAppModule(o));
var modules = typs.Select(o => CreateModule(services, o)).Distinct();
return modules.ToList();
}
protected virtual void SetServiceProvider(IServiceProvider serviceProvider)
{
ServiceProvider = serviceProvider;
ServiceProvider.GetRequiredService<ObjectAccessor<IServiceProvider>>().Value = ServiceProvider;
}
/// <summary>
/// 获取所有需要加载的模块
/// </summary>
/// <returns></returns>
protected virtual IReadOnlyList<IDSAppModule> LoadModules()
{
List<IDSAppModule> modules = new List<IDSAppModule>();
var module = Source.FirstOrDefault(o => o.GetType() == StartupModuleType);
//if (module == null)
//{
// throw new Exception($"类型为“{StartupModuleType.FullName}”的模块实例无法找到");
//}
Console.WriteLine("当前启动模块:", module);
modules.Add(module);
var dependeds = module.GetDependedTypes();
foreach (var dependType in dependeds.Where(o => DSAppModule.IsAppModule(o)))
{
var dependModule = Source.ToList().Find(m => m.GetType() == dependType);
if (dependModule == null)
{
throw new Exception($"加载模块{module.GetType().FullName}时无法找到依赖模块{dependType.FullName}");
}
modules.AddIfNotContains(dependModule);
}
return modules;
}
/// <summary>
/// 创建模块
/// </summary>
/// <param name="services"></param>
/// <param name="moduleType"></param>
/// <returns></returns>
private IDSAppModule CreateModule(IServiceCollection services, Type moduleType)
{
var module = (IDSAppModule)Expression.Lambda(Expression.New(moduleType)).Compile().DynamicInvoke();
services.AddSingleton(moduleType, module);
return module;
}
public virtual void Dispose()
{
}
}