.net core学习(八).NET中微软官方的IoC框架DependencyInjection

勇哥注:

依赖注、IoC容器、控制反转这些,勇哥已经发过许多贴子。下面这些供大家参考:

控制反转思想,来自生活与编程等各方面的例子

http://47.98.154.65/?id=2204


依赖倒置(反转)(DIP),控制反转(IoC),依赖注入(DI),IoC容器

http://47.98.154.65/?id=2198


载自知乎一篇非常好的介绍依赖倒置原则的文章

http://47.98.154.65/?id=2201


依赖注入 和 new 一个实例有什么区别吗?

http://47.98.154.65/?id=2197



依赖注入,在.net framework时,我们用得较多的是Unity,这个最早是微软维护的,后来变成社区维护。

这个东西比较牛,除了支持IoC,还支持aop。

在.net Core的时代,微软提供的官方ioc包就是本文要介绍的这个 Microsoft.Extensions.DependencyInjection


DI的一些基本概念


服务(service):对象;

注册服务;

服务容器:负责管理注册的服务

查询服务:创建对象及关联对象

对象生命周期:Transient(瞬态);Scoped(范围);Singleton(单例);



.NET中使用DI


根据类型来获取和注册服务

可以分别指定服务类型(service type)和实现类型( implementation type)。

这两者可能相同,也可能不同。

服务类型可以是类,也可以是接口,建议面向接口编程,更加灵活。


.NET的控制反转组件叫DependencyInjection,但它包含ServiceLocator的功能。

包名字叫: Microsoft.Extensions.DependencyInjection


使用流程:

ServiceCollection用来构造容器对象IServiceProvider。调用ServiceCollection的

BuildServiceProvider() 创建的 ServiceProvider,可以用来获取BuildServiceProvider()

之前ServiceCollection中的对象。



源码,服务定位器模式(ServiceLocator):

using Microsoft.Extensions.DependencyInjection;

namespace ConsoleApp1
{
    internal class Program
    {
        static void Main(string[] args)
        {
            ServiceCollection services = new ServiceCollection();
            services.AddTransient<TestService1>();
            using(ServiceProvider serviceProvider = services.BuildServiceProvider()) 
            {
                var testService = serviceProvider.GetService<TestService1>();
                testService.Name= "刘备";
                testService.SayHi();
            }
         
        }
    }


    public interface ITestService
    {
        public string Name { get; set; }
        public void SayHi();
    }

    public class TestService1 : ITestService
    {
        public string Name { get; set; }
        public void SayHi()
        {
            Console.WriteLine($"Hi,I'm {Name}");
        }
    }

    public class TestService2 : ITestService
    {
        public string Name { get; set; }
        public void SayHi()
        {
            Console.WriteLine($"你好,我是 {Name}");
        }
    }

}



源码,基于构造函数的DI注入方式 :

using Microsoft.Extensions.DependencyInjection;
using System.Security.Authentication.ExtendedProtection;

namespace ConsoleApp1
{
    internal class Program
    {

        static void Main(string[] args)
        {
            IServiceCollection services = new ServiceCollection();
            services.AddScoped<MyController,MyController>();
            services.AddScoped<ILog,MyLog>();
            services.AddScoped<IConfig,MyConfig>();
            services.AddScoped<IStorage,MyStorage>();

            //services.AddScoped(typeof(MyController), typeof(MyController));
            //services.AddScoped(typeof(ILog), typeof(MyLog));
            //services.AddScoped(typeof(IConfig), typeof(MyConfig));
            //services.AddScoped(typeof(IStorage), typeof(MyStorage));
           
            ServiceProvider sp=services.BuildServiceProvider();
            using(IServiceScope is1=sp.CreateScope())
            {
                MyController? con =is1.ServiceProvider.GetService<MyController>();
                con?.Test();
            }
        }
    }

    public class MyController
    {
        private readonly ILog log;
        private readonly IConfig config;
        private readonly IStorage storage;

        public MyController(ILog log, IConfig config, IStorage storage)
        {
            this.log = log;
            this.config = config;
            this.storage = storage;
        }

        public void Test()
        {
            log.Log($"读取配置[{config.Read("path")}]");
            log.Log("开始连接数据库");
            storage.Save();
            log.Log("关闭数据库连接");
        }
    }

    public interface ILog
    {
        void Log(string message);
    }

    public class MyLog : ILog
    {
        public void Log(string message)
        {
            Console.WriteLine(message);
        }
    }

    public interface IConfig
    {
        string Read(string message);
    }

    public class MyConfig : IConfig
    {
        public string Read(string message)
        {
            return $"从文件读取的配置项[{message}]";
        }
    }

    public interface IStorage
    {
        void Save();
    }

    public class MyStorage : IStorage
    {
        public void Save()
        {
            Console.WriteLine("文件存储成功");
        }
    }


}


image.png



本文出自勇哥的网站《少有人走的路》wwww.skcircle.com,转载请注明出处!讨论可扫码加群:
本帖最后由 勇哥,很想停止 于 2024-05-29 09:07:20 编辑

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

会员中心
搜索
«    2025年4月    »
123456
78910111213
14151617181920
21222324252627
282930
网站分类
标签列表
最新留言
    热门文章 | 热评文章 | 随机文章
文章归档
友情链接
  • 订阅本站的 RSS 2.0 新闻聚合
  • 扫描加本站机器视觉QQ群,验证答案为:halcon勇哥的机器视觉
  • 点击查阅微信群二维码
  • 扫描加勇哥的非标自动化群,验证答案:C#/C++/VB勇哥的非标自动化群
  • 扫描加站长微信:站长微信:abc496103864
  • 扫描加站长QQ:
  • 扫描赞赏本站:
  • 留言板:

Powered By Z-BlogPHP 1.7.2

Copyright Your skcircle.com Rights Reserved.

鄂ICP备18008319号


站长QQ:496103864 微信:abc496103864