美文网首页.NET
浅谈.Net Core依赖注入

浅谈.Net Core依赖注入

作者: BugChang | 来源:发表于2018-04-12 16:47 被阅读162次

    .Net Core开发也有一段时间了,虽然用的算不上精通,磕磕碰碰也都有过,不过也算是入门了,开发一般项目都没什么问题。
    最近群里弄出了个新名词(dnc),一开始我开不太适应,不过确实方便,以后就这么叫吧。

    .Net Core = DotNetCore = dnc

    提到dnc就不得不说无处不在的依赖注入,相信依赖注入的好处大家都知道了,简单点说就是我要什么你就给我送过来,别让我大老远的找你去拿

    依赖注入一般有两种用法:

    一:定义一个接口或者抽象类IA,然后类A实现IA,当然也可以A、B、C、D多个类实现IA

    二:直接定义类A、B、C等,不考虑派生类,直接注入到容器里。

    直接上例子比较直观:

    先定义一个接口

     public interface ITest
        {
            string GetName();
        }
    

    TestA实现ITest类

       public class TestA:ITest
        {
            public string GetName()
            {
                return "BugChang";
            }
        }
    

    然后我们去Startup里注册服务

    public void ConfigureServices(IServiceCollection services)
        {
            services.AddSingleton<ITest, TestA>();
            services.AddMvc();
        }
    

    服务注册很简单,类型一对一,ITest接口实现类TestA,
    这里有三种Add方法,分别代表不同的生命周期:

    • AddSingleton:单个实例,生命周期最长,无限长。

    • AddTransient:随用随销毁,生命周期最短。

    • AddScoped:生命周期在客户端与服务器的单次会话中,只要会话不结束,就不会被销毁。

    接下来是如何调用,调用很简单,这里再Controller层调用,只需要在构造函数里要求传入ITest类型的参数即可:

    private readonly ITest _test;
    public HomeController(ITest test)
    {
        _test = test;
    }
    

    看一下效果

    action代码

    public IActionResult Test()
    {
        ViewBag.Name = _test.GetName();
        return View();
    }
    

    view 代码

    <ul>
        <li>@ViewBag.Names</li>
    </ul>
    

    页面效果


    image.png

    不使用接口,不考虑派生类的用法基本上大同小异

    放一下代码供参考,类:

       public class Test
       {
           public string GetName()
           {
               return "BugChang";
           }
       }
    

    注册服务:

     services.AddSingleton<Test>();
    

    其他代码不变。

    是不是挺简单的,日常开发经常用到的还是有接口约束的,这样实际调用的时候我们只需要向容器要一个ITest类型的参数就可以,就算以后不用TestA来实现,改用TestB来实现我们也不许动其他代码,只需要在注册服务的时候改一下实现类即可:

    services.AddSingleton<ITest, TestB>();
    

    这样就可以达到解耦的目的


    看到这里可能还存在一些疑惑,如果我同时注册2个实现类会怎么样呢?我当初也被困惑到了,先看一看会发生什么
    我们先新建一个TestB继承ITest

      public class TestB:ITest
        {
            public string GetName()
            {
                return "张三";
            }
        }
    

    然后我们在ConfigureServices追加一条

     public void ConfigureServices(IServiceCollection services)
            {
                services.AddSingleton<ITest, TestA>();
                services.AddSingleton<ITest,TestB>();
                services.AddMvc();
            }
    

    然后我们看一下结果


    image.png

    其实从代码中我们也不难看出,我们只能获取到最后的一个实例,那这种情况怎么办呢,毕竟是比较常见的场景。

    我们修改一下代码

            private readonly IEnumerable<ITest> _test;
            public HomeController(IEnumerable<ITest> test)
            {
                _test = test;
            }
    
     public IActionResult Test()
            {
                ViewBag.Names= new List<string>();
                foreach (var sv in _test)
                {
                    (ViewBag.Names as List<string>).Add(sv.GetName());
                }
    
                return View();
            }
    
    <ul>
        @foreach (var name in ViewBag.Names as List<string>)
        {
            <li>@name</li>
        }
    </ul>
    

    跑起来看一下


    image.png

    这下两个就都出来了,这么简单的办法之前怎么就没啥头绪呢,我们拿到了多个实现类还可以循环就什么事情都可以做了

    还有一种方法就是获取IServiceProvider,是不是眼熟,没错就是Startup里面的ConfigureServices的参数,代码如下:

    private readonly IServiceProvider _serviceProvider;
    public HomeController(IServiceProvider serviceProvider)
    {
        serviceProvider = serviceProvider;
    }
    
    public IActionResult Test()
    {
        ViewBag.Names= new List<string>();
    
        foreach (var sv in _serviceProvider.GetServices<ITest>())
        {
            (ViewBag.Names as List<string>).Add(sv.GetName());
        }
    
        return View();
    }
    

    看一下效果:


    image.png

    怎么样不错吧


    之前看到好多人用autofac替代了自带DI,原因是不能像af那样批量注册服务,我觉得这都不是问题,这里就不多啰嗦了,想看的可以点下方链接

    利用ASP.netCore自带DI(DependencyInjection)实现批量依赖注入

    友情提示:我没用过,不过感觉没有问题。


    以上就是个人对dnc依赖注入的一点理解,不对的地方还请指点。

    相关文章

      网友评论

        本文标题:浅谈.Net Core依赖注入

        本文链接:https://www.haomeiwen.com/subject/nonxkftx.html