.NetCore 3.1 使用AutoFac實現Autowired
阿新 • • 發佈:2021-09-17
我們知道,.NetCore 中友好的IOC容器可以幫助我們很方面的建立物件的例項。
通常我們在構建了一個 .NetCore 專案,是使用建構函式的方式獲取物件的例項,然後再將例項的物件賦值在本類的屬性中,這種方式在本類使用的外部物件少時還好,但是多的時候,就會顯得很臃腫,不夠優雅。
熟悉 Java 同學都知道,Java 有@Autowired 註解,可以很方便的獲取物件例項,程式碼又很優雅,那我們是否可以在.Netcore 中也可以如此優雅的進行物件例項呢?答案是肯定的。
在Program 中增加
public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .UseServiceProviderFactory(new AutofacServiceProviderFactory()) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); });
建立AutoRegisterModule 繼承Autofac.Module(這裡要注意,BaseApiController 是封裝的 ControllerBase,如果你沒有進行封裝,請替換 BaseApiController 為 ControllerBase
public class AutoRegisterModule : Autofac.Module { protected override void Load(ContainerBuilder builder) { // 自動對整合 IDependency 介面的類進行註冊 Type baseType = typeof(IDependency); var compilationLibrary = DependencyContext.Default .CompileLibraries .Where(x=> !x.Serviceable && x.Type == "project") .ToList(); List<Assembly> assemblyList = new List<Assembly>(); foreach (var _compilation in compilationLibrary) { try { assemblyList.Add(AssemblyLoadContext.Default.LoadFromAssemblyName(new AssemblyName(_compilation.Name))); } catch (Exception ex) { Console.WriteLine(_compilation.Name + ex.Message); } } builder.RegisterAssemblyTypes(assemblyList.ToArray()) .Where(type => baseType.IsAssignableFrom(type) && !type.IsAbstract) .AsSelf() .AsImplementedInterfaces() .PropertiesAutowired() .InstancePerLifetimeScope(); //在控制器中使用屬性依賴注入,其中注入屬性必須標註為 public //注意屬性注入 發現為Null 需要在Startup.cs 的 ConfigureServices 方法下加入如下程式碼 //services.AddControllers().AddControllersAsServices(); var controllersTypesInAssembly = typeof(Startup).Assembly.GetExportedTypes() .Where(type => typeof(BaseApiController).IsAssignableFrom(type)).ToArray(); builder.RegisterTypes(controllersTypesInAssembly).PropertiesAutowired(); } }
在Startup 的ConfigureServices 中增加
public void ConfigureServices(IServiceCollection services) { //上面是其他的實現 services.AddControllers().AddControllersAsServices(); }
在Startup 的 ConfigureContainer 中增加
public void ConfigureContainer(ContainerBuilder builder) { //新增依賴注入例項,AutofacModuleRegister就繼承自Autofac.Module的類 builder.RegisterModule<AutoRegisterModule>(); }
定義完畢,以下是使用方式。
定義一個Service
public class TestService : IDependency { public string GetString() { return "hello jd"; } }
在 Controller 中使用他
public class Test1Controller : BaseApiController { public TestService service { get; set; } [HttpGet, Route("demo")] public string GetDemo() { string str = service.GetString(); return "demo"; } }
以上就是使用AutoFac實現Autowired的完整過程了,實踐過程中有問題歡迎留言討論。