builder.Services.AddHostedService<ClearLogTask>();
builder.Services.AddTransient<IOperationTransient, Operation>(); builder.Services.AddScoped<IOperationScoped, Operation>(); builder.Services.AddSingleton<IOperationSingleton, Operation>(); builder.Services.AddSingleton(new Operation()); builder.Services.AddScoped(typeof(Operation)); builder.Services.AddTransient(typeof(Operation));
builder.Services.AddSingleton(new Operation()); builder.Services.AddSingleton(typeof(Operation)); builder.Services.AddScoped(typeof(Operation)); builder.Services.AddTransient(typeof(Operation));
builder.Services.AddSingleton(new Operation("引數1","引數2"));
public static class IServiceCollectionExtension { public static void BatchRegisterServices(this IServiceCollection services) { var allAssembly = GetAllAssembly(); services.RegisterServiceByAttribute(ServiceLifetime.Singleton, allAssembly); services.RegisterServiceByAttribute(ServiceLifetime.Scoped, allAssembly); services.RegisterServiceByAttribute(ServiceLifetime.Transient, allAssembly); services.RegisterBackgroundService(allAssembly); } /// <summary> /// 通過 ServiceAttribute 批次註冊服務 /// </summary> /// <param name="services"></param> /// <param name="serviceLifetime"></param> private static void RegisterServiceByAttribute(this IServiceCollection services, ServiceLifetime serviceLifetime, List<Assembly> allAssembly) { List<Type> types = allAssembly.SelectMany(t => t.GetTypes()).Where(t => t.GetCustomAttributes(typeof(ServiceAttribute), false).Length > 0 && t.GetCustomAttribute<ServiceAttribute>()?.Lifetime == serviceLifetime && t.IsClass && !t.IsAbstract).ToList(); foreach (var type in types) { Type? typeInterface = type.GetInterfaces().FirstOrDefault(); if (typeInterface == null) { //服務非繼承自介面的直接注入 switch (serviceLifetime) { case ServiceLifetime.Singleton: services.AddSingleton(type); break; case ServiceLifetime.Scoped: services.AddScoped(type); break; case ServiceLifetime.Transient: services.AddTransient(type); break; } } else { //服務繼承自介面的和介面一起注入 switch (serviceLifetime) { case ServiceLifetime.Singleton: services.AddSingleton(typeInterface, type); break; case ServiceLifetime.Scoped: services.AddScoped(typeInterface, type); break; case ServiceLifetime.Transient: services.AddTransient(typeInterface, type); break; } } } } /// <summary> /// 註冊後臺服務 /// </summary> /// <param name="services"></param> /// <param name="serviceLifetime"></param> private static void RegisterBackgroundService(this IServiceCollection services, List<Assembly> allAssembly) { List<Type> types = allAssembly.SelectMany(t => t.GetTypes()).Where(t => typeof(BackgroundService).IsAssignableFrom(t) && t.IsClass && !t.IsAbstract).ToList(); foreach (var type in types) { services.AddSingleton(typeof(IHostedService), type); } } /// <summary> /// 獲取全部 Assembly /// </summary> /// <returns></returns> private static List<Assembly> GetAllAssembly() { var allAssemblies = AppDomain.CurrentDomain.GetAssemblies().ToList(); HashSet<string> loadedAssemblies = new(); foreach (var item in allAssemblies) { loadedAssemblies.Add(item.FullName!); } Queue<Assembly> assembliesToCheck = new(); assembliesToCheck.Enqueue(Assembly.GetEntryAssembly()!); while (assembliesToCheck.Any()) { var assemblyToCheck = assembliesToCheck.Dequeue(); foreach (var reference in assemblyToCheck!.GetReferencedAssemblies()) { if (!loadedAssemblies.Contains(reference.FullName)) { var assembly = Assembly.Load(reference); assembliesToCheck.Enqueue(assembly); loadedAssemblies.Add(reference.FullName); allAssemblies.Add(assembly); } } } return allAssemblies; } } [AttributeUsage(AttributeTargets.Class)] public class ServiceAttribute : Attribute { public ServiceLifetime Lifetime { get; set; } = ServiceLifetime.Transient; }
[Service(Lifetime = ServiceLifetime.Scoped)]
[Service(Lifetime = ServiceLifetime.Singleton)]
[Service(Lifetime = ServiceLifetime.Transient)]
像下面的 AuthorizeService 只要只要在頭部加上 [Service(Lifetime = ServiceLifetime.Scoped)]
[Service(Lifetime = ServiceLifetime.Scoped)] public class AuthorizeService { private readonly DatabaseContext db; private readonly SnowflakeHelper snowflakeHelper; private readonly IConfiguration configuration; public AuthorizeService(DatabaseContext db, SnowflakeHelper snowflakeHelper, IConfiguration configuration) { this.db = db; this.snowflakeHelper = snowflakeHelper; this.configuration = configuration; } /// <summary> /// 通過使用者id獲取 token /// </summary> /// <param name="userId"></param> /// <returns></returns> public string GetTokenByUserId(long userId) { //此處省略業務邏輯 } }
至於註冊後臺服務,則連裝飾屬性都不需要加,如下面的的一個後臺服務範例程式碼
public class ClearLogTask : BackgroundService { private readonly IServiceProvider serviceProvider; public DemoTask(IServiceProvider serviceProvider) { this.serviceProvider = serviceProvider; } protected override Task ExecuteAsync(CancellationToken stoppingToken) { return Task.Run(() => { var timer = new Timer(1000 * 5); timer.Elapsed += TimerElapsed; timer.Start(); }, stoppingToken); } private void TimerElapsed(object? sender, ElapsedEventArgs e) { //省略業務邏輯 } }
builder.Services.BatchRegisterServices();