.Net Core中IOC容器的使用

打代码之前先说一下几个概念,那就是什么是IOC、DI、DIP

虽然网上讲这些的已经有很多了,我这里还是要再赘述一下

IOC容器就是一个工厂,负责创建对象的
IOC控制反转:只是把上端对下端的依赖,换成第三方容器决定
DI依赖注入:就是在构造某个对象时,能将对象依赖的东西自动的初始化进去
正是因为要实现IOC,所以才诞生了DI的技术手段
DIP就是上层模块不应该依赖底层模块,它们都应该依赖于抽象,具体点是Service不应该依赖于Repository,而应该依赖于IRepository

.Net Core中自带了轻量级的IOC的容器

依次是Transient、Scoped、Singleton

services.AddTransient<>():服务在每次请求时被创建,适合无状态的服务

services.AddScoped<>():服务每个请求只创建一次

services.Singleton<>():单例,只创建一次,第一次被请求的时候被创建

code部分:

定义一个接口ICacheContext和一个实现类CacheContext

 

 假如我们现在想要使用CacheContext类中的方法,按照我们以前的思路肯定是:

//实例化
CacheContext context=new CacheContext();
//调用方法
context.method();

这就产生了依赖!我们要依赖于抽象不能依赖于具体实现细节,这样做:

//实例化
ICacheContext context=new CacheContext();
//调用方法
context.method();

接下来用IOC容器实现,将对象交给IOC容器托管。

这样之后可以使用构造函数、属性、方法进行注入

这里使用构造函数注入,如下:

 

 接下来使用第三方IOC容器:Autofac

导包:Autofac与Autofac.Extensions.DependencyInjection

在Program中,加入如下代码:

复制代码
 public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
            .UseServiceProviderFactory(new AutofacServiceProviderFactory())//配置UseServiceProviderFactory
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
复制代码

在Startup中加入一个方法:

 public void ConfigureContainer(ContainerBuilder builder)
        {
            builder.RegisterType<CacheContext>().As<ICacheContext>();
        }

还是一样在Controller中使用构造函数注入,和上面一样

但是在真实的项目开发中不可能一个个的写

我们可以通过反射加载程序集的强名称,但是api层必须要对其引用

例如我这里api层引用了Icewo.BaseManage.MSSQLDB层

 在ConfigureContainer方法中添加如下代码

 var assemblysServicesNoInterfaces = Assembly.Load("Icewo.BaseManage.MSSQLDB");
 builder.RegisterAssemblyTypes(assemblysServicesNoInterfaces);
Icewo.BaseManage.MSSQLDB层是没有实现层的,也就是说他没有接口层
如果是有接口层的话,方法又不一样了

例如我这里有Business层和IBusiness层,如果api层直接对Business层进行引用,这就造成程序高度耦合。所以api层只引用IBusiness层 DIP(依赖倒置)

 在ConfigureContainer中添加如下方法:

注意:你要拷贝Business.dll到api层的bin目录下或者改一下输出路径,不然启动的时候会报错。

 var basePath = Microsoft.DotNet.PlatformAbstractions.ApplicationEnvironment.ApplicationBasePath;
 var businessDllFile = Path.Combine(basePath, "Icewo.BaseManage.Business.dll");
 var assemblysBusiness = Assembly.LoadFrom(businessDllFile);
 builder.RegisterAssemblyTypes(assemblysBusiness)
 .AsImplementedInterfaces()
 .InstancePerDependency();

还是一样在Controllers中以构造函数注入的方式进行调用

水平有限,但是希望能帮到大家。

END

 

 
 

 

作者:江北

出处:https://www.cnblogs.com/zhangnever/p/12324133.html

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

微信:CodeDoraemon

posted @   江北、  阅读(3129)  评论(4编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示
more_horiz
keyboard_arrow_up dark_mode palette
选择主题
晓看天色暮看云