.NET 6 整合 Autofac 依赖注入容器

  • .NET 6 整合 Autofac 依赖注入容器已关闭评论
  • 121 次浏览
  • A+
所属分类:.NET技术
摘要

一行业务代码还没写,框架代码一大堆,不利于学习。
常看到java的学习资料或博客,标题一般为《SpringBoot 整合 XXX》,所以仿照着写了《.NET 6 整合 Autofac 依赖注入容器》这样一个标题。
以下是我自己的用法,可能不是最佳实践。


前言

一行业务代码还没写,框架代码一大堆,不利于学习。
常看到java的学习资料或博客,标题一般为《SpringBoot 整合 XXX》,所以仿照着写了《.NET 6 整合 Autofac 依赖注入容器》这样一个标题。
以下是我自己的用法,可能不是最佳实践。

一. 引用包

NuGet搜索并安装:
Autofac
Autofac.Extensions.DependencyInjection

二. 配置代码

var builder = WebApplication.CreateBuilder(args);  ...省略  // ASP.NET Core整合Autofac builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());//通过工厂替换,把Autofac整合进来 builder.Host.ConfigureContainer<ContainerBuilder>(containerBuilder => {     ServiceFactory.SetBuilder(containerBuilder);     ServiceFactory.RegisterAssembly(Assembly.GetExecutingAssembly()); //注册服务 });  var app = builder.Build();  ServiceFactory.SetContainer((app.Services as AutofacServiceProvider).LifetimeScope as IContainer); Task.Run(async () => await ServiceFactory.StartAllService()); //启动服务,注意:服务启动完成之前,调用接口会异常  ...省略  

三. 服务的自动注册、启动、停止

IService接口

/// <summary> /// 服务接口 /// </summary> public interface IService {     /// <summary>     /// 服务启动     /// </summary>     Task OnStart();      /// <summary>     /// 服务停止     /// </summary>     Task OnStop(); } 

RegisterServiceAttribute特性

/// <summary> /// 注册为服务 /// </summary> public class RegisterServiceAttribute : Attribute { } 

ServiceBase抽像类

[RegisterService] public abstract class ServiceBase : IService {     #region OnStart     public virtual Task OnStart()     {         return Task.CompletedTask;     }     #endregion      #region OnStop     public virtual Task OnStop()     {         return Task.CompletedTask;     }     #endregion  } 

ServiceFactory服务工厂类

public class ServiceFactory {     private static ContainerBuilder _builder;      private static IContainer _container;      private static bool _isRunning; //服务是否正在运行      public static void SetBuilder(ContainerBuilder builder)     {         _builder = builder;     }      public static void SetContainer(IContainer container)     {         _container = container;     }      /// <summary>     /// Autofac.ContainerBuilder     /// </summary>     public static ContainerBuilder Builder     {         get         {             return _builder;         }     }      /// <summary>     /// 获取服务     /// </summary>     /// <typeparam name="T">接口类型</typeparam>     public static T Get<T>()     {         if (_isRunning)         {             return _container.Resolve<T>();         }         else         {             throw new Exception("服务尚未启动完成");         }     }      /// <summary>     /// 获取服务     /// </summary>     /// <param name="type">接口类型</param>     public static object Get(Type type)     {         if (_isRunning)         {             return _container.Resolve(type);         }         else         {             throw new Exception("服务尚未启动完成");         }     }      #region 注册程序集     /// <summary>     /// 注册程序集     /// </summary>     /// <param name="serviceAssembly">服务程序集</param>     public static void RegisterAssembly(Assembly serviceAssembly)     {         Type[] typeArr = serviceAssembly.GetTypes();          foreach (Type type in typeArr)         {             if (type.GetCustomAttribute<RegisterServiceAttribute>() != null && !type.IsAbstract)             {                 _builder.RegisterType(type).SingleInstance().AsImplementedInterfaces().AsSelf();             }             else             {                 Type[] interfaceTypes = type.GetInterfaces();                 foreach (Type interfaceType in interfaceTypes)                 {                     if (interfaceType.GetCustomAttribute<RegisterServiceAttribute>() != null && !type.IsAbstract)                     {                         _builder.RegisterType(type).SingleInstance().AsImplementedInterfaces().AsSelf();                         break;                     }                 }             }         }          //_container = _builder.Build();     }     #endregion      #region 启动所有服务     /// <summary>     /// 启动所有服务     /// </summary>     public static async Task StartAllService()     {         Type iServiceInterfaceType = typeof(IService);         IEnumerable<Type> types = _container.ComponentRegistry.Registrations.Select(a => a.Activator.LimitType);         await Parallel.ForEachAsync(types, async (type, c) =>         {             if (iServiceInterfaceType.IsAssignableFrom(type))             {                 object obj = _container.Resolve(type);                  try                 {                     IService service = obj as IService;                     await service.OnStart();                     LogUtil.Info("服务 " + obj.GetType().FullName + " 已启动");                 }                 catch (Exception ex)                 {                     LogUtil.Error(ex, "服务 " + obj.GetType().FullName + " 启动失败");                 }             }         });         _isRunning = true;     }     #endregion      #region 停止所有服务     /// <summary>     /// 停止所有服务     /// </summary>     public static async Task StopAllService()     {         Type iServiceInterfaceType = typeof(IService);         IEnumerable<Type> types = _container.ComponentRegistry.Registrations.Select(a => a.Activator.LimitType);         await Parallel.ForEachAsync(types, async (type, c) =>         {             if (iServiceInterfaceType.IsAssignableFrom(type))             {                 object obj = _container.Resolve(type);                 IService service = obj as IService;                  try                 {                     await service.OnStop();                     LogUtil.Info("服务 " + obj.GetType().FullName + " 已停止");                 }                 catch (Exception ex)                 {                     LogUtil.Error(ex, "服务 " + obj.GetType().FullName + " 停止失败");                 }             }         });         _isRunning = false;     }     #endregion  } 

ServiceFactory的简写类

/// <summary> /// ServiceFactory的简写 /// </summary> public class SF {     /// <summary>     /// 获取服务     /// </summary>     /// <typeparam name="T">接口类型</typeparam>     public static T Get<T>()     {         return ServiceFactory.Get<T>();     }      /// <summary>     /// 获取服务     /// </summary>     /// <param name="type">接口类型</param>     public static object Get(Type type)     {         return ServiceFactory.Get(type);     } } 

编写服务类

服务类示例1

/// <summary> /// 测试服务 /// </summary> public class TestService : ServiceBase {     public async Task<string> GetValue()     {         return await Task.FromResult("测试数据");     } } 

服务类示例2

重写了OnStart和OnStop以实现服务的启动和停止。

/// <summary> /// 定时任务管理 /// </summary> public class ScheduleJobs : ServiceBase {     #region 变量     private IScheduler _scheduler;     #endregion      #region OnStart     public override async Task OnStart()     {         try         {             NameValueCollection options = new NameValueCollection();             string schedulerName = "DefaultQuartzScheduler";             options.Add("quartz.scheduler.instanceName", schedulerName);             StdSchedulerFactory schedulerFactory = new StdSchedulerFactory(options);             _scheduler = await schedulerFactory.GetScheduler(schedulerName);             if (_scheduler == null)             {                 _scheduler = await schedulerFactory.GetScheduler();             }             await _scheduler.Start();             AddJobs(_scheduler);         }         catch (Exception ex)         {             Console.WriteLine(ex.ToString());         }     }     #endregion      #region OnStop     public override async Task OnStop()     {         await _scheduler.Shutdown();     }     #endregion      #region ScheduleJob     private async Task ScheduleJob<T>(IScheduler scheduler, string cronString) where T : IJob     {         IJobDetail jobDetail = JobBuilder.Create<T>().Build();         ITrigger trigger = TriggerBuilder.Create().WithCronSchedule(cronString).Build();         await scheduler.ScheduleJob(jobDetail, trigger);     }     #endregion      private async void AddJobs(IScheduler scheduler)     {         await ScheduleJob<TestJob>(scheduler, "0/30 * * * * ?");     }  } 

构造注入示例

[ApiController] [Route("[controller]")] public class TestController : ControllerBase {     private readonly TestService _testService;      public TestController(TestService testService)     {         _testService = testService;     }      ...省略 } 

也可以这样使用

var value = await SF.Get<TestService>().GetValue();