NetCore 中间件之Autofac(依赖注入)的基本使用(Netcore2.X)1.2

本文是介绍netcore2.x版本的autofac的使用,以下是netcore3.0的
NetCore3.0面向接口编程中,Autofac(依赖注入)的基本使用

项目基本介绍

备注,项目源代码在上传GitHub后会展示链接
在这里插入图片描述
项目用的面向接口编程
(PS:面向接口编程的核心含义就是,层与层之间只通过接口关联)
EptDemo是API主程序:依赖于IRepo和IServ
EptDemo.IRepo是仓储接口层,负责提供Repo层的接口
EptDemo.Repo是仓储层,负责与数据库进行数据串接,依赖Repo
EptDemo.IServ是服务接口层,一般只提供给主程序,依赖于IRepo
EptDemo.Serv是服务层,作用是完成与Repo层的数据串接,依赖于IRepo和IServe层

autofac实现依赖注入

安装扩展包

管理nugut安装下载Autofac及其扩展包

Autofac.Extensions.DependencyInjection
Autofac.Extras.DynamicProxy

注册服务

在startup.cs中ConfigureServices中注册
先写最简单的代码

基本

            //获取项目路径
            var basePath = AppContext.BaseDirectory;            
            //初始化AutoFac容器
            var builder = new ContainerBuilder();
            
            #region 可升级代码
           //普通注入,与netcore本身提供netcore一致
            builder.RegisterType<DemoServices>().As<IDemoServices>();
            builder.RegisterType<DemoRepository>().As<IDemoRepository>();
            #endregion
            
           //将services填充Autofac容器生成器            
            builder.Populate(services);
            //使用已创建的组件登记创建新容器
            var ApplicationContainer = builder.Build();
            //第三方IOC接管 core内置DI容器
            return new AutofacServiceProvider(ApplicationContainer);
           

效果和 services.AddScoped<IDemoServices, DemoServices>();一致
注意:以上代码需要添加repository和services的引用

进阶

实际上,我们的services和repository后续会越来越多,这样做会很麻烦,那能不能一次性全部匹配呢。答案是可以的
进阶一:反射加载
通过反射加载程序集,然后进行依赖注入
将“可升级代码”更新成以下代码

            #region 加载引用注入
            //通过反射加载services程序集
            var assemblyServices = Assembly.Load("EptDemo2.Services");
            //指定已扫描程序集中的类型注册为提供所有其实现的接口
            builder.RegisterAssemblyTypes(assemblyServices).AsImplementedInterfaces();

            //通过反射加载repository
            var assemblyRepository = Assembly.Load("EpteDemo2.Repository");
            builder.RegisterAssemblyTypes(assemblyRepository).AsImplementedInterfaces();
            #endregion

作用:就是通过命名空间,反射加载程序集,然后达成依赖注入的效果
注意:此方法也需要services层和repository层的引用,这样才能访问到对应的命名空间

进阶二:松耦合
批量注入的效果是达到了,但是有一个效果没有达到,就是松耦合。
我们面向接口编程其实最重要的就是为了达成这种效果。而上面的代码,依然还是需要添加repository和serivices的引用,那其实耦合度还是比较高。
而这个时候,如果想要达成效果,一般会采用加载dll的方法。
步骤一:更换dll生成路径

  • 将repository和services的dll生成路径放到主程序上(EptDemo2):右键repository -属性-编译-输出路径:将路径改为 …\EptDemo2\bin\Debug\
  • services同上
  • 重新编译这两个项目(右键项目-编译)
    注意:输出路径是两个 逗号

在这里插入图片描述
步骤二:将“可升级代码”更新成如下

            var basePath = AppContext.BaseDirectory;
            var servicesDllFile = Path.Combine(basePath, "EptDemo2.Services.dll");
            var assemblyServices = Assembly.LoadFile(servicesDllFile);
            builder.RegisterAssemblyTypes(assemblyServices).AsImplementedInterfaces();

            var repositoryDllFile = Path.Combine(basePath, "EptDemo2.Repository.dll");
            var assemblyRepository = Assembly.LoadFile(repositoryDllFile);
            builder.RegisterAssemblyTypes(assemblyRepository).AsImplementedInterfaces();

之后将整个解决方案,重新编译即可
此种方法,在每次更新repository和services的代码时,都需要重新编译才能生效。
切记切记

常见异常:

None of the constructors found with ‘Autofac.Core.Activators.Reflection.DefaultConstructorFinder’ on type ‘EptDemo2.Services.DemoServices’ can be invoked with the available services and parameters:
Cannot resolve parameter ‘EptDemo2.IRepository.IDemoRepository demoRepository’ of constructor ‘Void .ctor(EptDemo2.IRepository.IDemoRepository)’.
这种问题的根因是在于autofac没有找到匹配的匹配的实现。
可能原因

  • 在autofac中,没有找到对应的实现代码,例如IServices没有找到Servcies的实例。
    那问题就在于auto部分代码写错。最有可能的就是dll文件路径加了I,写成了IRepository。-_-别问我咋知道
  • .在serviecs中,没有写构造函数,导致没有把repository写入到services的构造方法,如下图
    在这里插入图片描述
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值