<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          .NET 7 中 Autofac 依賴(lài)注入整合多層,項(xiàng)目中可直接用

          共 10741字,需瀏覽 22分鐘

           ·

          2023-08-17 02:50


          ?一、配置Autofac替換內(nèi)置DI
          1、安裝Nuget包:Autofac.Extensions.DependencyInjection

          2、Program.cs中加上

          builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());
          builder.Host.ConfigureContainer<ContainerBuilder>(containerBuilder =>
          {
              //在這里寫(xiě)注入代碼
          });

          二、構(gòu)造函數(shù)注入

          新建IUserService,類(lèi)UserService

          public interface IUserService
          {
              public string GetUserName();
          }
          public class UserServiceIUserService
          {
              public string GetUserName()
              {
                  return "張三";
              }
          }

          在上面的ConfigureContainer方法把UserService注入進(jìn)來(lái),默認(rèn)是瞬時(shí)注入

          瞬時(shí)注入

          containerBuilder.RegisterType<UserService>().As<IUserService>().InstancePerDependency();

          單例注入

          containerBuilder.RegisterType< UserService >().As< IUserService>().SingleInstance();

          生命周期注入

          containerBuilder.RegisterType<UserService>().As<IUserService>().InstancePerLifetimeScope();

          注入試下是否注入成功

          調(diào)用成功,證明注入成功

          三、屬性注入

          1、把HomeController改成屬性注入形式,屬性注入有一個(gè)問(wèn)題,就是那些屬性需要注入?

          全部注入沒(méi)必要,父類(lèi)也有很多屬性,要按需注入,給屬性增加一個(gè)自定義特性標(biāo)識(shí)說(shuō)明需要注入。

          public class HomeController : Controller
          {
              [AutowiredProperty]
              private IUserService userService { getset; }
              public IActionResult Index()
              {
                  string name = userService.GetUserName();
                    return View();
              }
          }

          2、新增自定義特性類(lèi)AutowiredPropertyAttribute.cs

          [AttributeUsage(AttributeTargets.Property)]
          //為了支持屬性注入,只能打到屬性上
          public class AutowiredPropertyAttributeAttribute
          {
          }

          3、增加識(shí)別特性類(lèi)AutowiredPropertySelector.cs

          public class AutowiredPropertySelector : IPropertySelector
          {
              public bool InjectProperty(PropertyInfo propertyInfo, object instance)
              {
                  //判斷屬性的特性是否包含自定義的屬性,標(biāo)記有返回true
                  return propertyInfo.CustomAttributes.Any(s => s.AttributeType == typeof(AutowiredPropertyAttribute));
              }
          }

          4、因?yàn)镃ontroller 默認(rèn)是由 Mvc 模塊管理的,需要把控制器放到IOC容器中,在Program.cs中增加

          //讓控制器實(shí)例由容器創(chuàng)建
          builder.Services.Replace(ServiceDescriptor.Transient<IControllerActivator, ServiceBasedControllerActivator>());

          5、把容器注冊(cè)到IOC容器,在Program.cs的ConfigureContainer()增加

          //獲取所有控制器類(lèi)型并使用屬性注入
          Type[] controllersTypeAssembly = typeof(Program).Assembly.GetExportedTypes()
              .Where(type => typeof(ControllerBase).IsAssignableFrom(type)).ToArray();
          containerBuilder.RegisterTypes(controllersTypeAssembly).PropertiesAutowired(new AutowiredPropertySelector());

          驗(yàn)證:

          成功。

          四、批量注入

          實(shí)際項(xiàng)目中那么多需要注入的類(lèi),一個(gè)個(gè)寫(xiě)注冊(cè)就不太現(xiàn)實(shí)了,需要一個(gè)可以批量注入的方法。

          1、新建三個(gè)空接口IScopeDenpendency.cs,ISingletonDenpendency.cs,ITransitDenpendency.cs

          /// <summary>
          /// 瞬時(shí)注入
          /// </summary>
          public interface ITransitDenpendency
          {
          }
          /// <summary>
          /// 單例注入標(biāo)識(shí)
          /// </summary>
          public interface ISingletonDenpendency
          {
          }
          /// <summary>
          /// 生命周期注入標(biāo)識(shí)
          /// </summary>
          public interface IScopeDenpendency
          {
          }

          2、把上面要注入的類(lèi)實(shí)現(xiàn)上面的接口

          3、新增一個(gè)IocManager類(lèi)

          /// <summary>
          /// Ioc管理
          /// </summary>
          public static class IocManager
          {
               /// <summary>
               /// 批量注入擴(kuò)展
               /// </summary>
               /// <param name="builder"></param>
               /// <param name="assembly"></param>
               public static void BatchAutowired(this ContainerBuilder builder, Assembly assembly)
               {

                   var transientType = typeof(ITransitDenpendency); //瞬時(shí)注入
                   var singletonType = typeof(ISingletonDenpendency); //單例注入
                   var scopeType = typeof(IScopeDenpendency); //單例注入
                   //瞬時(shí)注入
                   builder.RegisterAssemblyTypes(assembly).Where(t => t.IsClass && !t.IsAbstract && t.GetInterfaces().Contains(transientType))
                       .AsSelf()
                       .AsImplementedInterfaces()
                       .InstancePerDependency()
                       .PropertiesAutowired(new AutowiredPropertySelector());
                   //單例注入
                   builder.RegisterAssemblyTypes(assembly).Where(t => t.IsClass && !t.IsAbstract && t.GetInterfaces().Contains(singletonType))
                      .AsSelf()
                      .AsImplementedInterfaces()
                      .SingleInstance()
                      .PropertiesAutowired(new AutowiredPropertySelector());
                   //生命周期注入
                   builder.RegisterAssemblyTypes(assembly).Where(t => t.IsClass && !t.IsAbstract && t.GetInterfaces().Contains(scopeType))
                      .AsSelf()
                      .AsImplementedInterfaces()
                      .InstancePerLifetimeScope()
                      .PropertiesAutowired(new AutowiredPropertySelector());
               }
          }

          4、把注入類(lèi)ConfigureContainer改成

          5、防止Program.cs代碼過(guò)多,建一個(gè)Module把注入代碼搬走,新建AutofacRegisterModule.cs類(lèi)把ConfigureContainer的代碼移過(guò)去

          public class AutofacRegisterModule : Autofac.Module
          {
              protected override void Load(ContainerBuilder builder)
              {
                  //獲取所有控制器類(lèi)型并使用屬性注入
                  Type[] controllersTypeAssembly = typeof(Program).Assembly.GetExportedTypes()
                      .Where(type => typeof(ControllerBase).IsAssignableFrom(type)).ToArray();
                  builder.RegisterTypes(controllersTypeAssembly).PropertiesAutowired(new AutowiredPropertySelector());
                  //批量自動(dòng)注入,把需要注入層的程序集傳參數(shù),注入Service層的類(lèi)
                  builder.BatchAutowired(typeof(UserService).Assembly);
                  //注入其它層的containerBuilder.BatchAutowired(typeof(其它層的任務(wù)一個(gè)類(lèi)).Assembly);
              }
          }

          ConfigureContainer的代碼變成

          五、手動(dòng)獲取實(shí)例

          手動(dòng)獲取實(shí)例的場(chǎng)景有靜態(tài)幫助類(lèi)中獲取實(shí)例,例如redisHelper中獲取注入的配置文件中的連接字符串

          1、在上面的IocManager類(lèi)中增加

          private static object obj = new object();
          private static ILifetimeScope _container { getset; }

          public static void InitContainer(ILifetimeScope container)
          {
              //防止過(guò)程中方法被調(diào)用_container發(fā)生改變
              if (_container == null)
              {
                  lock (obj)
                  {
                      if (_container == null)
                      {
                          _container = container;
                      }
                  }
              }
          }
          /// <summary>
          /// 手動(dòng)獲取實(shí)例
          /// </summary>
          /// <typeparam name="T"></typeparam>
          /// <returns></returns>
          public static T Resolve<T>()
          {
              return _container.Resolve<T>();
          }

          2、在Program.cs中增加

          3、驗(yàn)證,新建一個(gè)DataHelper.cs類(lèi)

          public class DataHelper
          {
              //手動(dòng)注入U(xiǎn)serService
              private static IUserService userService = IocManager.Resolve<IUserService>();
              public static string GetData()
              {
                  return userService.GetUserName();
              }
          }

          成功獲取到值,證明從容器中獲取成功。

          六、其它用法

          1、不用接口,直接注入實(shí)例?

          ?
          public class UserService :ITransitDenpendency  

             public string GetUserName()  
             { 
               return "張三";  
             }  
          }

          2、一接口多實(shí)現(xiàn)

          public class UserService :IUserService
          {
              public string GetUserName()
              {
                  return "張三";
              }
          }

          public class UserService2 : IUserService
          {
              public string GetUserName()
              {
                  return "張三2號(hào)";
              }
          }

          轉(zhuǎn)自:包子wxl

          鏈接:cnblogs.com/wei325/p/17481596.html

          瀏覽 149
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  在线观看黄日本免费 | 真正免费av | 熟女一区二区 | 小h片免费在线观看 | 久久黄色视屏 |