.NetCore 3.1 使用AutoFac实现Autowired
我们知道,.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的完整过程了,实践过程中有问题欢迎留言讨论。