目录
前言
Autofac
添加一个 Util 来随时调用
小结
代码地址
预告
前言
周末加班, 下午犯困, 整理下之前鼓捣过的东西, 看过我之前的 webapi 系列的读者知道, 我之前试过 Aspect, 但是升级到 3.0 之后没往下去试了, 当时还留了个坑, 这不, 现在果断移除了换成这个了.
Autofac
这个第三方类库呢, 是 IoC 的容器, 可以简化我们很大的工作量, 比如说在之前我们需要写个类去声明接口与实现, 而用了这个容器呢, 就不需要了, 当然还是需要些配置的.
首先, 引入第三方类库, 不多说.
然后开始配置吧, 首先先来看 Program, 添加 AutofacServiceProviderFactory.
- public static IHostBuilder CreateHostBuilder(string[] args) =>
- Host.CreateDefaultBuilder(args)
- .ConfigureWebHostDefaults(webBuilder =>
- {
- webBuilder.UseStartup<Startup>();
- })
- .UseServiceProviderFactory(new AutofacServiceProviderFactory());
改完之后呢, 我们果断就来到了 Startup, 只要是配置, 当然要看入口文件跟这个配置文件了.
3.x 呢有个变化就是 Autofac 要通过 ConfigureContainer 这个传入容器的方法来配置了, 不需要自己再创建.
- private static readonly List<string> _Assemblies = new List<string>()
- {
- "April.Service"
- };
- public void ConfigureContainer(ContainerBuilder container)
- {
- var assemblys = _Assemblies.Select(x => Assembly.Load(x)).ToList();
- List<Type> allTypes = new List<Type>();
- assemblys.ForEach(aAssembly =>
- {
- allTypes.AddRange(aAssembly.GetTypes());
- });
- // 通过 Autofac 自动完成依赖注入
- container.RegisterTypes(allTypes.ToArray())
- .AsImplementedInterfaces()
- .PropertiesAutowired()
- .InstancePerDependency();
- // 注册 Controller
- container.RegisterAssemblyTypes(typeof(Startup).GetTypeInfo().Assembly)
- .Where(t => typeof(Controller).IsAssignableFrom(t) && t.Name.EndsWith("Controller", StringComparison.Ordinal))
- .PropertiesAutowired();
- }
通过 RegisterTypes 的注册方法将对应工程, 也就是 April.Service 下的类接口与实现自动绑定, 当然你也可以通过注册接口的方法一个个来, 但是我懒, 比如:
- // 一个
- builder.RegisterType<StudentService>().As<IStudentService>();
- // 一对多
- builder.RegisterType<StudentService>().As<IStudentService>().As<ITestService>();
这里注意, 声明绑定一般是一对一, 当然也可以是一对多, 如果多次注册声明一个类, 会取最后一次注册的声明作为实际操作的类.
好了, 配置完成之后, 我们来试下效果吧 (当然我是已经注释掉之前的 ServiceInjection 这个声明方法了).
在我们访问 Values 的时候, 我们看下 IStudentService 是否是 null.
OK, 这已经说明通过 Autofac 这个容器, 已经完成了一个工程里面的接口与实现的依赖关系了.
添加一个 Util 来随时调用
在接触的朋友中, 有人给我反馈个信息, 我不想每次写方法都要构造函数来传接口方法给我, 也就是说我不要你觉得, 我要我觉得.
好啊, 你觉得方法自己要啥拿啥, 可以, 来个 Util 吧.
- public class AutofacUtil
- {
- public static ILifetimeScope Container { get; set; }
- /// <summary>
- /// 获取服务 (Single)
- /// </summary>
- /// <typeparam name="T"> 接口类型 </typeparam>
- /// <returns></returns>
- public static T GetService<T>() where T : class
- {
- return Container.Resolve<T>();
- }
- /// <summary>
- /// 获取服务 (请求生命周期内)
- /// </summary>
- /// <typeparam name="T"> 接口类型 </typeparam>
- /// <returns></returns>
- public static T GetScopeService<T>() where T : class
- {
- return (T)GetService<IHttpContextAccessor>().HttpContext.RequestServices.GetService(typeof(T));
- }
- }
在用之前, 我们需要针对 Container 来个声明实例化, Startup 中的 Configure 添加下面一句.
AutofacUtil.Container = App.ApplicationServices.GetAutofacRoot();
修改 Values 中的一部分来通过实例化的方式来调用接口.
- IStudentService studentService = AutofacUtil.GetScopeService<IStudentService>();
- StudentEntity entity = new StudentEntity
- {
- // 新增
- Name = "小明",
- Age = 18,
- Number = "007",
- Sex = 0,
- Address = "大洛阳"
- };
- studentService.Insert(entity);
让我们来看下效果吧.
两种方法, 看个人习惯吧, 我是推荐通过注入的方式, 通过构造函数的方式来获取接口实现.
小结
简单记录平时鼓捣的点点滴滴, 有时候真是觉得, 还是要多看多鼓捣, 就像这个容器, 在之前我通过一行一行的接口 + 实现来做绑定声明, 现在呢, 只需要改造下, 就可以一键无脑实例化, 第三方库的使用与否, 个人觉得还是能踩着巨人的肩膀哪怕靠着也可以, 自己一步步爬固然可嘉, 也要学会变通, 这样方能提高效率, 路漫漫其修远兮.
代码地址
注意切换到 3.0 的分支.
- https://github.com/AprilBlank/April.WebApi
- https://gitee.com/AprilBlank/April.WebApi
预告
April-Admin, 总算是要有个前后端联动的工程了, 一个名副其实的基础工程.
前端基于 Ant Design Pro
后端当然是 net core 3.1 了
来源: https://www.cnblogs.com/AprilBlank/p/12111733.html