依赖注入框架Castle Windsor从容器里解析一个实例时(也就是调用Resolve方法),是通过调用待解析对象的构造函数new一个对象并返回,那么问题是:它是调用哪个构造函数呢?

  • 无参的构造函数
  • 带参但参数不是靠依赖注入的构造函数
  • 带参且参数是靠依赖注入的构造函数
  • 有多个带参且参数是靠依赖注入的构造函数

带着这个问题,我写了一段测试代码.

测试1:

只有一个无参构造函数:

CtorTest类(在控制台程序里用Windsor解析这个类)

  1. public class CtorTest
  2. {
  3.  
  4. public string Message { get; set; }
  5.  
  6. public CtorTest()
  7. {
  8. Message = $"The message is from {nameof(CtorTest)}";
  9. }
  10.  
  11. public void ShowMessage()
  12. {
  13. Console.WriteLine(Message);
  14. }
  15. }

控制台Main代码如下所示:

  1. class Program
  2. {
  3. static void Main(string[] args)
  4. {
  5. IWindsorContainer iocContainer = new WindsorContainer();
  6. iocContainer.Register(Component.For<CtorTest>().ImplementedBy<CtorTest>().LifestyleSingleton());
  7.  
  8. var instance = iocContainer.Resolve<CtorTest>();
  9. instance.ShowMessage();
  10. }
  11. }

测试结果(默认构造函数与无参构造函数性质是一样的):

测试2

只有一个带参但不是靠依赖注入的构造函数(没有无参数构造函数)

CtorTest代码如下:

  1. public string Message { get; set; }
  2.  
  3. public CtorTest(string message)
  4. {
  5. Message = $"The message is from {nameof(CtorTest)}";
  6. }
  7.  
  8. public void ShowMessage()
  9. {
  10. Console.WriteLine(Message);
  11. }
  12. }

测试结果,当然是抛出异常:

如果为这个参数提供默认值(如:string message=""),Resolve会调用这个构造函数,如果再加一个无参构造函数,Resolve会调用带参的,如再加一个带有两个带默认值的带参构造函数,则会调用两个参数的,所以这里的结论是:带有默认值的有参(先参数个数多的),再无参.

测试3:

有一个带参且参数是靠依赖注入的构造函数,和一个无参数构造函数,一个两个具有默认值参数的构造函数.

添加一个Sub类:

  1. public class Sub
  2. {
  3. public string Message { get; set; }
  4.  
  5. public Sub()
  6. {
  7. Message = $"The message is from {nameof(Sub)}";
  8. }
  9. }

Ctor类代码如下:

  1. public class CtorTest
  2. {
  3.  
  4. public string Message { get; set; }
  5.  
  6. public CtorTest()
  7. {
  8. Message = $"The message is from {nameof(CtorTest)}";
  9. }

      public CtorTest(string message = "message1",string message2= "message2")
      {
        Message = $"The message is from {nameof(CtorTest)} and {message} and {message2}" ;
      }

  1. public CtorTest(Sub sub)
  2. {
  3. Message = sub.Message;
  4. }
  5.  
  6. public CtorTest(string message = "")
  7. {
  8. Message = $"The message is from {nameof(CtorTest)}";
  9. }
  10.  
  11. public void ShowMessage()
  12. {
  13. Console.WriteLine(Message);
  14. }
  15. } 

Main如下:

  1. class Program
  2. {
  3. static void Main(string[] args)
  4. {
  5. IWindsorContainer iocContainer = new WindsorContainer();
  6. iocContainer.Register(Component.For<CtorTest>().ImplementedBy<CtorTest>().LifestyleSingleton());
           //把sub注入到容器中
  7. iocContainer.Register(Component.For<Sub>().ImplementedBy<Sub>().LifestyleSingleton());

  8. var instance = iocContainer.Resolve<CtorTest>();
  9. instance.ShowMessage();
  10. }
  11. }

测试结果:

从结果可以看出它是通过带参(参数是依赖注入)的构造函数创建实例,即使在有一个2个具有默认值的参数的构造函数的情况下.

测试4

两个带参且参数是靠依赖注入的构造函数

添加一个Sub2类:

  1. public class Sub2
  2. {
  3. public string Message { get; set; }
  4.  
  5. public Sub2()
  6. {
  7. Message = $"The message is from {nameof(Sub2)}";
  8. }
  9. }

Ctor类代码如下:

  1. public class CtorTest
  2. {
  3.  
  4. public string Message { get; set; }
  5.  
  6. public CtorTest()
  7. {
  8. Message = $"The message is from {nameof(CtorTest)}";
  9. }
  10.  
  11. //注意:我故意把这个放到sub参数的构造函数前面
  12. public CtorTest(Sub2 sub2)
  13. {
  14. Message = sub2.Message;
  15. }

  16. public CtorTest(Sub sub)
  17. {
  18. Message = sub.Message;
  19. }
  20.  
  21. public CtorTest(string message = "")
  22. {
  23. Message = $"The message is from {nameof(CtorTest)}";
  24. }
  25.  
  26. public void ShowMessage()
  27. {
  28. Console.WriteLine(Message);
  29. }
  30. }

Main类代码如下:

  1. class Program
  2. {
  3. static void Main(string[] args)
  4. {
  5. IWindsorContainer iocContainer = new WindsorContainer();
  6. iocContainer.Register(Component.For<CtorTest>().ImplementedBy<CtorTest>().LifestyleSingleton());
           //把sub2注入到容器中,注意我故意把sub2放到sub前面
  7. iocContainer.Register(Component.For<Sub2>().ImplementedBy<Sub2>().LifestyleSingleton());
  8. //把sub注入到容器中
  9. iocContainer.Register(Component.For<Sub>().ImplementedBy<Sub>().LifestyleSingleton());
  10.  
  11. var instance = iocContainer.Resolve<CtorTest>();
  12. instance.ShowMessage();
  13. }
  14. }

测试结果:

尽管我把Sub2的构造函数和注册都放在了Sub前面,但最终还是调用了带Sub参数的构造函数.那么它的顺序是什么呢?通过修改类的名称(比如说把Sub2改成排序在Sub前的名称,如S,那么就会调用S这个参数的构造函数)

测试5

有两个带参且参数是靠依赖注入的构造函数

把CtorTest类里的

  1. public CtorTest(Sub2 sub2)
  2. {
  3. Message = sub2.Message;
  4. }

修改成

  1. public CtorTest(Sub2 sub2,Sub sub)
  2. {
  3. Message = sub2.Message +Environment.NewLine + sub.Message;
  4. }

测试结果:

它调用的是修改后的这个构造函数,也就是说:它先调用了参数多的那个.

最终总终:

Resolve先调用参数个数多且参数通过依赖注入的构造函数,如果参数个数相同的构造函数有多个,则按参数类型名称(这个名称应该是完全限定名,没有测试)顺序,调用第一个,如果不存在这样的构造函数,则优先调用参数个数多且具有默认值的构造函数.

对Castle Windsor的Resolve方法的解析时new对象的探讨的更多相关文章

  1. Castle Windsor Ioc 一个接口多个实现解决方案

    介绍 Castle Windsor 是微软的Ioc类库,本文主要介绍解决一个接口多个实现的解决方案 接口和类 以下内容不是真实的实际场景,仅仅是提供解决一个接口多个实现的思路. 业务场景类 先假设有一 ...

  2. Castle Windsor常用介绍以及其在ABP项目的应用介绍

    最近在研究ABP项目,有关ABP的介绍请看阳光铭睿 博客,ABP的DI和AOP框架用的是Castle Windsor下面就对Castle Windsor项目常用方法介绍和关于ABP的使用总结 1.下载 ...

  3. 在ABP项目的应用Castle Windsor

    Castle Windsor常用介绍以及其在ABP项目的应用介绍 最近在研究ABP项目,有关ABP的介绍请看阳光铭睿 博客,ABP的DI和AOP框架用的是Castle Windsor下面就对Castl ...

  4. [转载]es6 Promise.resolve()方法

    es6 Promise.resolve()方法 2018-01-27 22:29:06 ixygj197875 阅读数 16925更多 分类专栏: ES6标准入门 (阮一峰) ES6标准入门   Pr ...

  5. 说说ABP项目中的AutoMapper,Castle Windsor(痛并快乐着)

    这篇博客要说的东西跟ABP,AutoMapper和Castle Windsor都有关系,而且也是我在项目中遇到的问题,最终解决了,现在的感受就是“痛并快乐着”. 首先,这篇博客不是讲什么新的知识点,而 ...

  6. [Castle Windsor]学习依赖注入

    初次尝试使用Castle Windsor实现依赖注入DI,或者叫做控制反转IOC. 参考: https://github.com/castleproject/Windsor/blob/master/d ...

  7. IoC - Castle Windsor 2.1

    找过一些Windsor教程的文章,博客园上TerryLee有写了不少,以及codeproject等也有一些例子,但都讲的不太明了.今天看到Alex Henderson写的一个系列,非常简单明了.下面是 ...

  8. Castle Windsor 项目中快速使用

    Castle Windsor 项目中快速使用 新建项目如下: 一个模型类,一个接口,一个实现方法.我的目的很明确就是在UI层通过Castle 调用数据访问层的方法. 添加项目引用 CastleDemo ...

  9. c# Castle Windsor简单例子

    Windsor是Castle的IOC框架.需要用到两个dll(Castle.Core.dll和Castle.Windsor.dll). 1.接口以及接口实现类: public interface IT ...

随机推荐

  1. 移动硬盘不能识别的常见7种解决方案 ~ By 逆天经验

    服务器汇总:http://www.cnblogs.com/dunitian/p/4822808.html#iis 服务器异常: http://www.cnblogs.com/dunitian/p/45 ...

  2. 红黑树——算法导论(15)

    1. 什么是红黑树 (1) 简介     上一篇我们介绍了基本动态集合操作时间复杂度均为O(h)的二叉搜索树.但遗憾的是,只有当二叉搜索树高度较低时,这些集合操作才会较快:即当树的高度较高(甚至一种极 ...

  3. 神马玩意,EntityFramework Core 1.1又更新了?走,赶紧去围观

    前言 哦,不搞SQL了么,当然会继续,周末会继续更新,估计写完还得几十篇,但是我会坚持把SQL更新完毕,绝不会烂尾,后续很长一段时间没更新的话,不要想我,那说明我是学习新的技能去了,那就是学习英语,本 ...

  4. [.NET] C# 知识回顾 - Event 事件

    C# 知识回顾 - Event 事件 [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/6060297.html 序 昨天,通过<C# 知识回顾 - ...

  5. 【Python五篇慢慢弹】快速上手学python

    快速上手学python 作者:白宁超 2016年10月4日19:59:39 摘要:python语言俨然不算新技术,七八年前甚至更早已有很多人研习,只是没有现在流行罢了.之所以当下如此盛行,我想肯定是多 ...

  6. 利用apply()或者rest参数来实现用数组传递函数参数

    关于call()和apply()的用法,MDN文档里写的非常清晰明白,在这里就不多做记录了. https://developer.mozilla.org/zh-CN/docs/Web/JavaScri ...

  7. 在centos7中添加一个新用户,并授权

    前言 笔记本装了一个centos,想要让别人也可以登录访问,用自己的账号确实不太好,于是准备新建一个用户给他. 创建新用户 创建一个用户名为:zhangbiao [root@localhost ~]# ...

  8. DirectX Graphics Infrastructure(DXGI):最佳范例 学习笔记

    今天要学习的这篇文章写的算是比较早的了,大概在DX11时代就写好了,当时龙书11版看得很潦草,并没有注意这篇文章,现在看12,觉得是跳不过去的一篇文章,地址如下: https://msdn.micro ...

  9. JQuery阻止事件冒泡

    冒泡事件就是点击子节点,会向上触发父节点,祖先节点的点击事件. 我们在平时的开发过程中,肯定会遇到在一个div(这个div可以是元素)包裹一个div的情况,但是呢,在这两个div上都添加了事件,如果点 ...

  10. [Hadoop in Action] 第6章 编程实践

    Hadoop程序开发的独门绝技 在本地,伪分布和全分布模式下调试程序 程序输出的完整性检查和回归测试 日志和监控 性能调优   1.开发MapReduce程序   [本地模式]        本地模式 ...