zoukankan      html  css  js  c++  java
  • .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

     
     
  • 相关阅读:
    分页的实现
    调取地图map
    meta标签应用,适应手机屏幕以及关键词、描述的添加
    页面中公共部分的统一调用
    PC端变成手机端的时候,把特效去掉(把canvas标签去掉)
    IIS上绑定域名,发布上线
    动态截取字符串获取当前网页的URL地址
    Vue 打包后报错 Uncaught TypeError: Cannot redefine property: $router
    Vue项目部署到线上页面空白
    让从后台返回的数据在让elementui 的el-select 显示对应的label值而不是value值
  • 原文地址:https://www.cnblogs.com/zhangnever/p/12324133.html
Copyright © 2011-2022 走看看