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

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

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

测试1:

只有一个无参构造函数:

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

   public class CtorTest
{ public string Message { get; set; } public CtorTest()
{
Message = $"The message is from {nameof(CtorTest)}";
} public void ShowMessage()
{
Console.WriteLine(Message);
}
}

控制台Main代码如下所示:

class Program
{
static void Main(string[] args)
{
IWindsorContainer iocContainer = new WindsorContainer();
iocContainer.Register(Component.For<CtorTest>().ImplementedBy<CtorTest>().LifestyleSingleton()); var instance = iocContainer.Resolve<CtorTest>();
instance.ShowMessage();
}
}

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

测试2

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

CtorTest代码如下:

 public string Message { get; set; }

        public CtorTest(string message)
{
Message = $"The message is from {nameof(CtorTest)}";
} public void ShowMessage()
{
Console.WriteLine(Message);
}
}

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

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

测试3:

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

添加一个Sub类:

    public class Sub
{
public string Message { get; set; } public Sub()
{
Message = $"The message is from {nameof(Sub)}";
}
}

Ctor类代码如下:

  public class CtorTest
{ public string Message { get; set; } public CtorTest()
{
Message = $"The message is from {nameof(CtorTest)}";
}

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

public CtorTest(Sub sub)
{
Message = sub.Message;
} public CtorTest(string message = "")
{
Message = $"The message is from {nameof(CtorTest)}";
} public void ShowMessage()
{
Console.WriteLine(Message);
}

Main如下:

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

var instance = iocContainer.Resolve<CtorTest>();
instance.ShowMessage();
}
}

测试结果:

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

测试4

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

添加一个Sub2类:

    public class Sub2
{
public string Message { get; set; } public Sub2()
{
Message = $"The message is from {nameof(Sub2)}";
}
}

Ctor类代码如下:

    public class CtorTest
{ public string Message { get; set; } public CtorTest()
{
Message = $"The message is from {nameof(CtorTest)}";
} //注意:我故意把这个放到sub参数的构造函数前面
public CtorTest(Sub2 sub2)
{
Message = sub2.Message;
}

public CtorTest(Sub sub)
{
Message = sub.Message;
} public CtorTest(string message = "")
{
Message = $"The message is from {nameof(CtorTest)}";
} public void ShowMessage()
{
Console.WriteLine(Message);
}
}

Main类代码如下:

    class Program
{
static void Main(string[] args)
{
IWindsorContainer iocContainer = new WindsorContainer();
iocContainer.Register(Component.For<CtorTest>().ImplementedBy<CtorTest>().LifestyleSingleton());
       //把sub2注入到容器中,注意我故意把sub2放到sub前面
iocContainer.Register(Component.For<Sub2>().ImplementedBy<Sub2>().LifestyleSingleton());
//把sub注入到容器中
iocContainer.Register(Component.For<Sub>().ImplementedBy<Sub>().LifestyleSingleton()); var instance = iocContainer.Resolve<CtorTest>();
instance.ShowMessage();
}
}

测试结果:

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

测试5

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

把CtorTest类里的

        public CtorTest(Sub2 sub2)
{
Message = sub2.Message;
}

修改成

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

测试结果:

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

最终总终:

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. 如何一步一步用DDD设计一个电商网站(六)—— 给购物车加点料,集成售价上下文

    阅读目录 前言 如何在一个项目中实现多个上下文的业务 售价上下文与购买上下文的集成 结语 一.前言 前几篇已经实现了一个最简单的购买过程,这次开始往这个过程中增加一些东西.比如促销.会员价等,在我们的 ...

  2. 常见CSS与HTML使用误区

       误区一.多div症 <div class="nav"> <ul> <li><a href="/home/"> ...

  3. Android 获取meta-data中的数据

    在 Android 的 Mainfest 清单文件中,Application,Activity,Recriver,Service 的节点中都有这个的存在.很多时候我们可以通过 meta-data 来配 ...

  4. 玩转spring boot——结合AngularJs和JDBC

    参考官方例子:http://spring.io/guides/gs/relational-data-access/ 一.项目准备 在建立mysql数据库后新建表“t_order” ; -- ----- ...

  5. Java实现Excel中的NORMSDIST函数和NORMSINV函数

    由于工作中需要将Excel中的此两种函数转换成java函数,从而计算内部评级的资本占用率和资本占用金额.经过多方查阅资料和整理,总结出如下两个转换方法 标准正态分布累计函数NORMSDIST: pub ...

  6. javascript arguments(转)

    什么是arguments arguments 是是JavaScript里的一个内置对象,它很古怪,也经常被人所忽视,但实际上是很重要的.所有主要的js函数库都利用了arguments对象.所以agru ...

  7. 使用HEXO快速建站

    先安好npm,请参照:http://max.cszi.com/archives/482 打开网站:https://hexo.io/   npm install hexo-cli -g hexo ini ...

  8. 面向未来的友好设计:Future Friendly

    一年前翻译了本文的一部分,最近终于翻译完成.虽然此设计思想的提出已经好几年了,但是还是觉得应该在国内推广一下,让大家知道“内容策略”,“移动优先”,“响应式设计”,“原子设计”等设计思想和技术的根源. ...

  9. IM 去中心化概念模型与架构设计

    今天打算写写关于 IM 去中心化涉及的架构模型变化和设计思路,去中心化的概念就是说用户的访问不是集中在一个数据中心,这里的去中心是针对数据中心而言的. 站在这个角度而言,实际上并非所有的业务都能做去中 ...

  10. 最新Linux部署.NET,Mono and DNX

    这几天一直在折腾在Linux下的ASP.NET 5,就下在看来在其它操作系统中ASP.NET 5或.NET应用,要想在完整的MS VM(CoreCLR)上运行还不远远达不到,应用的效果. 目前只能在M ...