基础拾遗------------依赖注入

前言

  好久没有写微博了,因为前段时间由于家庭原因决定从工作了3年多的北京转移到上海去。依赖注入在学习net core的时候也有写过类似的东西,只是实践的较少,结果来到上海新公司系统框架涉及到了这块知识点,所以在了解完自己的项目之后决定做一些相关的总结。接下来就让我们先来了解hewi依赖注入。

什么是依赖注入

  依赖注入,全称是“依赖注入到容器”, 容器(IOC容器)是一个设计模式,它也是个对象,你把某个类(不管有多少依赖关系)放入这个容器中,可以“解析”出这个类的实例。所以依赖注入就是把有依赖关系的类放入容器(IOC容器)中,然后解析出这个类的实例。划重点:依赖注入是为了实现控制反转的一种设计模式。【现在知道gof之外还有其他的设计模式了吧。】

为什么要用依赖注入

  我们编程希望高内聚低耦合,所以解耦是很多理论的出发点,依赖注入控制反转也是为了解耦。那么冒昧问一下啊低耦合是什么?我的理解就是:我们在编程过程中,我们不需要知道组件与类库的内容只需知道他们提供的接口,调用接口就能实现功能,我们就说这种情况是低耦合

  在没有接触到依赖注入的时候,解耦的思路其实也就是gof设计模式和设计原则。我以前分享的很多文章牵涉到的封装类库都是基于面向接口的方式。举个例子:

public interface IOrder
{
//Product 产品对象
decimal ValueProducts(params Product[] products);
}

public class Order : IOrder
{
public decimal ValueProducts(params Product[] products)
{
return products.Sum(p => p.Price*p.Number);
}
}

以上是在做商城经常写的一个基类。比如我们以前商城中购物车下单就算其总价的方法调用的时候。

  public class ShoppingCart
        {
            //计算购物车内商品总价钱
            public decimal CalculateStockValue()
            {
                Product[] products = {
              new Product {Name = "龙牙2016新款", Number=2,ModelNo = 121,ColorID=65,SizeID=78, Price = 289.40},
              new Product {Name = "龙牙2017新款", ModelNo = 121,ColorID=65,SizeID=78, Number=2,Price =3800},
          };
                IOrder order = new Order();
                //计算商品总价钱 
                decimal totalValue = order.ValueProducts(products);
                return totalValue;
            }
        }

 以上是我常用的方式来处理自己的业务需求的。这种面向接口的方式,如果我们要计算金额的方式改变了,比如我们尺寸32的金额打7折,那么只需增加金额的类。改变接口实例化即可。代码就不敲了应该都懂吧(低耦合)。那么我们可以看出ShoppingCart是依赖于接口与实现的对不对,那么现在我们考虑一个问题,购物车虽然调用接口实例化,但是它也是要依赖于order的,那么减少它的依赖性有没有办法——就是把他们完全分开。那么这种问题的解决就用到了依赖注入了。划重点:依赖注入就是减少对接口实例化对象的依赖。那么怎么来实现依赖注入呢?

构造注入的实现

通过类的构造函数

第一次看net core别人也是讲的这种方式,下面看一下代码。设置一个服务类接口类型的数据成员,并以构造函数为注入点,这个构造函数接受一个具体的服务类实例为参数,并将它赋给服务类接口类型的数据成员。

 1  public class ShoppingCart
 2         {
 3             IOrder order;
 4             //构造函数,参数为实现了IOrder 接口的类的实例
 5             public ShoppingCart(IOrder _order)
 6             {
 7                 order = _order;
 8             }
 9             //计算购物车内商品总价钱
10             public decimal CalculateStockValue()
11             {
12                 Product[] products = {
13                     new Product {Name = "龙牙2016新款", Number=2,ModelNo = 121,ColorID=65,SizeID=78, Price = 289.40},
14                    new Product {Name = "龙牙2017新款", ModelNo = 121,ColorID=65,SizeID=78, Number=2,Price =3800}}; //计算商品总价钱 
15                 decimal totalValue = order.ValueProducts(products);
16                 return totalValue;
17             }

以上代码最秒的地方就是ShoppingCart与接口IOrder的实现order完全没有关系,不需要了解他是怎么实现的。这就是依赖注入。这种叫做构造注入。

在我们讨论下一种注入的方式的时候,有个问题其实还没有解决。“依赖是如何产生的?”把依赖当作构造函数参数来写,尽管使用这可以手动提供这种依赖,但是当整个系统都依赖注入,那就意味着任何一个组件我们都需要知如道满足每一部分的需求(服务定位器),是不是很头大?那么这时我们就要要引入一个概念的“容器”-----依赖注入容器。

 protected override void RegisterBuilder(ContainerBuilderWrapper builder)
        {
            base.RegisterBuilder(builder);
      //注入仓储
            builder.RegisterType<Order>().As<IOrder>();
        }
以上为mvc容器的一种实现。AS 后边是服务类继承的接口,其实我对它的理解就是:如果有人请求这种类型。我们就给他这个类型的对象。

 属性注入

其实依赖注入spring相关的资料应该有很多,所以很多知识点也是通过java那的理论借鉴过来的。属性注入我确实看的net的书了解的。

如果需要使用到被依赖对象的某个属性,在被依赖对象被创建之后,IoC容器会自动初始化该属性

首先还是定一个接口

    public interface Iorder
        {
            {
            //Product 产品对象
            decimal ValueProducts(params Product[] products);
            }
        }

属性注入如下:

  public class ShoppingCart
        {
            private iordre _order;
            public iordre Order
            {
                get { return _order; }
                set { _order = value; }
            }
            public decimal ValueProducts(params Product[] products)
            {
                return Order.ValueProducts(products);
            }
        }

Setter注入

设置一个服务类接口类型的数据成员,并设置一个Set方法作为注入点,这个Set方法接受一个具体的服务类实例为参数,并将它赋给服务类接口类型的数据成员。其实这种是注入方式较为灵活使用者也较多。

   //服务接口
        internal interface IServiceClass
        {
            String ServiceInfo();
        }

        //服务方法
        internal class ServiceClassA : IServiceClass
        {
            public String ServiceInfo()
            {
                return "我是ServceClassA";
            }
        }
        //服务方法
        internal class ServiceClassB : IServiceClass
        {
            public String ServiceInfo()
            {
                return "我是ServceClassB";
            }
        }
        //客户类实现set
        internal class ClientClass
        {
            private IServiceClass _serviceImpl;

            public void Set_ServiceImpl(IServiceClass serviceImpl)
            {
                this._serviceImpl = serviceImpl;
            }

            public void ShowInfo()
            {
                Console.WriteLine(_serviceImpl.ServiceInfo());
            }
        }

        //调用
        class Program
        {
            static void Main(string[] args)
            {
                IServiceClass serviceA = new ServiceClassA();
                IServiceClass serviceB = new ServiceClassB();
                ClientClass client = new ClientClass();

                client.Set_ServiceImpl(serviceA);
                client.ShowInfo();
                client.Set_ServiceImpl(serviceB);
                client.ShowInfo();
            }
        }

结束语

其实依赖注入可聊的有很多,net core的出现依赖注入是必不可少的一个知识点。后面可聊的比如依赖注入与反射,依赖注入与多态,依赖注入的框架。。。。。。。

好久不写博客,准备的也不够充分。有兴趣的小伙伴就去网上找去吧。

.net书的话:

《asp net mvc5 高级编程》《Dependency Injection in .NET 》(没有中文)

java相关的书应该会多一些。有兴趣的就一起学习一下吧。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏牛客网

今日头条三面面经

4.       优先队列的底层数据结构?插入和删除一个节点的时间复杂度是多少? 

282
来自专栏机器学习从入门到成神

2017年小米春招内推面试面经

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sinat_35512245/articl...

561
来自专栏H2Cloud

Event Store框架探究

摘要:   游戏开发中,经常会越到千奇百怪的Bug。后台程序都是以demon 方式运行,要么GDB,要么Log。一些确定性的bug可以直接使用GDB调试,比如特...

3457
来自专栏海说

晚期(运行期)优化

  即时编译器(Just In Time Compiler)为了提高执行效率将热点代码编译成与本地平台相关的机器码,并进行各种层次的优化的编译器。它并不是虚拟机...

1820
来自专栏撸码那些事

我看依赖注入

1163
来自专栏Linyb极客之路

简洁又快速地处理集合——Java8 Stream(上)

本篇文章主要是让大家能够理解 Stream,理解它的基本原理,理解我们为什么需要使用 Stream 以及它的好处,而具体的实战环节我会在下篇文章中讲解。

973
来自专栏数据结构与算法

P1629 邮递员送信

题目描述 有一个邮递员要送东西,邮局在节点1.他总共要送N-1样东西,其目的地分别是2~N。由于这个城市的交通比较繁忙,因此所有的道路都是单行的,共有M条道路,...

2667
来自专栏HBStream流媒体与音视频技术

MP4大文件虚拟HLS分片技术,避免服务器大量文件碎片

对于大家经常见到和使用到的普通MP4来说,作为电影、电视文件的存储容器,是很好的,不过对于流媒体点播来说,最大的缺点就是它的媒体信息和关键帧索引都集中存放在mo...

49612
来自专栏程序猿DD

探讨通过Feign配合Hystrix进行调用时异常的处理

作者:任聪 原文:http://www.jianshu.com/p/f240ca7bb7c0 前言:此文所述处理方式为本人在实践过程中研究分析得出的一种解决方案...

3025
来自专栏恰同学骚年

设计模式的征途—10.装饰(Decorator)模式

虽然目前房价依旧很高,就连我所在的成都郊区(非中心城区)的房价均价都早已破万,但却还是阻挡不了大家对新房的渴望和买房的热情。如果大家买的是清水房,那么无疑还有一...

633

扫描关注云+社区