对Castle Windsor的Resolve方法的解析时new对象的探讨
依赖注入框架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对象的探讨的更多相关文章
- Castle Windsor Ioc 一个接口多个实现解决方案
介绍 Castle Windsor 是微软的Ioc类库,本文主要介绍解决一个接口多个实现的解决方案 接口和类 以下内容不是真实的实际场景,仅仅是提供解决一个接口多个实现的思路. 业务场景类 先假设有一 ...
- Castle Windsor常用介绍以及其在ABP项目的应用介绍
最近在研究ABP项目,有关ABP的介绍请看阳光铭睿 博客,ABP的DI和AOP框架用的是Castle Windsor下面就对Castle Windsor项目常用方法介绍和关于ABP的使用总结 1.下载 ...
- 在ABP项目的应用Castle Windsor
Castle Windsor常用介绍以及其在ABP项目的应用介绍 最近在研究ABP项目,有关ABP的介绍请看阳光铭睿 博客,ABP的DI和AOP框架用的是Castle Windsor下面就对Castl ...
- [转载]es6 Promise.resolve()方法
es6 Promise.resolve()方法 2018-01-27 22:29:06 ixygj197875 阅读数 16925更多 分类专栏: ES6标准入门 (阮一峰) ES6标准入门 Pr ...
- 说说ABP项目中的AutoMapper,Castle Windsor(痛并快乐着)
这篇博客要说的东西跟ABP,AutoMapper和Castle Windsor都有关系,而且也是我在项目中遇到的问题,最终解决了,现在的感受就是“痛并快乐着”. 首先,这篇博客不是讲什么新的知识点,而 ...
- [Castle Windsor]学习依赖注入
初次尝试使用Castle Windsor实现依赖注入DI,或者叫做控制反转IOC. 参考: https://github.com/castleproject/Windsor/blob/master/d ...
- IoC - Castle Windsor 2.1
找过一些Windsor教程的文章,博客园上TerryLee有写了不少,以及codeproject等也有一些例子,但都讲的不太明了.今天看到Alex Henderson写的一个系列,非常简单明了.下面是 ...
- Castle Windsor 项目中快速使用
Castle Windsor 项目中快速使用 新建项目如下: 一个模型类,一个接口,一个实现方法.我的目的很明确就是在UI层通过Castle 调用数据访问层的方法. 添加项目引用 CastleDemo ...
- c# Castle Windsor简单例子
Windsor是Castle的IOC框架.需要用到两个dll(Castle.Core.dll和Castle.Windsor.dll). 1.接口以及接口实现类: public interface IT ...
随机推荐
- 移动硬盘不能识别的常见7种解决方案 ~ By 逆天经验
服务器汇总:http://www.cnblogs.com/dunitian/p/4822808.html#iis 服务器异常: http://www.cnblogs.com/dunitian/p/45 ...
- 红黑树——算法导论(15)
1. 什么是红黑树 (1) 简介 上一篇我们介绍了基本动态集合操作时间复杂度均为O(h)的二叉搜索树.但遗憾的是,只有当二叉搜索树高度较低时,这些集合操作才会较快:即当树的高度较高(甚至一种极 ...
- 神马玩意,EntityFramework Core 1.1又更新了?走,赶紧去围观
前言 哦,不搞SQL了么,当然会继续,周末会继续更新,估计写完还得几十篇,但是我会坚持把SQL更新完毕,绝不会烂尾,后续很长一段时间没更新的话,不要想我,那说明我是学习新的技能去了,那就是学习英语,本 ...
- [.NET] C# 知识回顾 - Event 事件
C# 知识回顾 - Event 事件 [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/6060297.html 序 昨天,通过<C# 知识回顾 - ...
- 【Python五篇慢慢弹】快速上手学python
快速上手学python 作者:白宁超 2016年10月4日19:59:39 摘要:python语言俨然不算新技术,七八年前甚至更早已有很多人研习,只是没有现在流行罢了.之所以当下如此盛行,我想肯定是多 ...
- 利用apply()或者rest参数来实现用数组传递函数参数
关于call()和apply()的用法,MDN文档里写的非常清晰明白,在这里就不多做记录了. https://developer.mozilla.org/zh-CN/docs/Web/JavaScri ...
- 在centos7中添加一个新用户,并授权
前言 笔记本装了一个centos,想要让别人也可以登录访问,用自己的账号确实不太好,于是准备新建一个用户给他. 创建新用户 创建一个用户名为:zhangbiao [root@localhost ~]# ...
- DirectX Graphics Infrastructure(DXGI):最佳范例 学习笔记
今天要学习的这篇文章写的算是比较早的了,大概在DX11时代就写好了,当时龙书11版看得很潦草,并没有注意这篇文章,现在看12,觉得是跳不过去的一篇文章,地址如下: https://msdn.micro ...
- JQuery阻止事件冒泡
冒泡事件就是点击子节点,会向上触发父节点,祖先节点的点击事件. 我们在平时的开发过程中,肯定会遇到在一个div(这个div可以是元素)包裹一个div的情况,但是呢,在这两个div上都添加了事件,如果点 ...
- [Hadoop in Action] 第6章 编程实践
Hadoop程序开发的独门绝技 在本地,伪分布和全分布模式下调试程序 程序输出的完整性检查和回归测试 日志和监控 性能调优 1.开发MapReduce程序 [本地模式] 本地模式 ...