CloudBuilder/CloudBuilder.Core/Application/Builders/CloudBuilderBuilder.cs
owenchen 1c0c83af5f ow
2026-05-12 10:09:31 +08:00

141 lines
4.7 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using CloudBuilder.Core.Application.Options;
using CloudBuilder.Core.Application.Packs;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Security.AccessControl;
using System.Text;
using System.Threading.Tasks;
namespace CloudBuilder.Core.Application.Builders
{
/// <summary>
/// CloudBuilder构建器
/// </summary>
public class CloudBuilderBuilder
{
public CloudBuilderBuilder(IServiceCollection services, IConfiguration configuration)
{
this.Services = services;
AddOptions(configuration);
}
/// <summary>
/// 获取 服务集合
/// </summary>
public IServiceCollection Services { get; }
/// <summary>
/// 获取 CloudBuilder选项配置委托
/// </summary>
public CloudBuilderOptions CloudBuilderOptions { get; private set; }
/// <summary>
/// 添加所有模块
/// </summary>
/// <typeparam name="TPack">要添加的模块类型</typeparam>
public CloudBuilderBuilder AddPack()
{
var baseType = typeof(CloudBuilderPack);
var allAssemblies = GetAssemblies();
var types = allAssemblies
.SelectMany(a => a.DefinedTypes)
.Select(type => type.AsType())
.Where(type => type != baseType && baseType.IsAssignableFrom(type))
.Where(x => x.IsClass)
.OrderBy(x => x.GetCustomAttribute<PackLevelAttribute>()?.Level).ToList();
foreach (var implementType in types)
{
if (Services.Any(m => m.ServiceType == baseType && m.ImplementationType == implementType))
{
continue;
}
//注入CloudBuilderPack模块内的服务
CloudBuilderPack pack = (CloudBuilderPack)Activator.CreateInstance(
implementType,
BindingFlags.Public | BindingFlags.Instance,
null,
null,
null);
pack.AddServices(Services, this);
}
return this;
}
/// <summary>
/// 添加CloudBuilder选项配置
/// </summary>
/// <param name="optionsAction">CloudBuilder操作选项</param>
/// <returns>CloudBuilder构建器</returns>
public CloudBuilderBuilder AddOptions(IConfiguration configuration)
{
CloudBuilderOptions options = new CloudBuilderOptions();
new CloudBuilderOptionsSetup(configuration).Configure(options);
CloudBuilderOptions = options;
return this;
}
public T GetTransientService<T>()
{
object? t = Services.BuildServiceProvider().GetService(typeof(T));
if (t == null) return default(T)!;
return (T)t;
}
public T GetTransientRequiredService<T>()
{
return (T)Services.BuildServiceProvider().GetRequiredService(typeof(T));
}
public static Assembly[] GetAssemblies()
{
// 获取入口程序集
var entryAssembly = Assembly.GetEntryAssembly();
List<string> reference = new List<string>();
if (!string.IsNullOrWhiteSpace(entryAssembly.Location))
{
var dependencyContext = DependencyContext.Default;
// 读取项目程序集或 Furion 官方发布的包或手动添加引用的dll或配置特定的包前缀
reference = dependencyContext.RuntimeLibraries
.Where(u => u.Type == "project" || u.Type == "reference")
.Select(x => x.Name).ToList();
}
string[] filters =
{
"mscorlib",
"netstandard",
"dotnet",
"api-ms-win-core",
"runtime.",
"System",
"Microsoft",
"Window",
};
//遍历文件夹的方式,用于传统.netfx
string path = AppContext.BaseDirectory;
string[] files = Directory.GetFiles(path, "*.dll", SearchOption.TopDirectoryOnly)
.Where(x => reference.Contains(Path.GetFileNameWithoutExtension(x))).ToArray();
return files.Where(file => filters.All(token => Path.GetFileName(file)?.StartsWith(token) != true)).Select(Assembly.LoadFrom).ToArray();
}
}
}