博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
对Castle Windsor的Resolve方法的解析时new对象的探讨
阅读量:6885 次
发布时间:2019-06-27

本文共 4856 字,大约阅读时间需要 16 分钟。

依赖注入框架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
().ImplementedBy
().LifestyleSingleton()); var instance = iocContainer.Resolve
(); 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
().ImplementedBy
().LifestyleSingleton());        //把sub注入到容器中 iocContainer.Register(Component.For
().ImplementedBy().LifestyleSingleton()); var instance = iocContainer.Resolve
(); 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
().ImplementedBy
().LifestyleSingleton());        //把sub2注入到容器中,注意我故意把sub2放到sub前面 iocContainer.Register(Component.For
().ImplementedBy
().LifestyleSingleton()); //把sub注入到容器中 iocContainer.Register(Component.For
().ImplementedBy().LifestyleSingleton()); var instance = iocContainer.Resolve
(); 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先调用参数个数多且参数通过依赖注入的构造函数,如果参数个数相同的构造函数有多个,则按参数类型名称(这个名称应该是完全限定名,没有测试)顺序,调用第一个,如果不存在这样的构造函数,则优先调用参数个数多且具有默认值的构造函数.

 

转载地址:http://nanbl.baihongyu.com/

你可能感兴趣的文章
RAID-10 阵列的创建(软)
查看>>
小菜鸡进阶之路-First week
查看>>
【原创翻译】布尔值(boolean)
查看>>
关于scrapy的piplines
查看>>
通向架构师的道路(第一天)之Apache整合Tomcat - lifetragedy的专栏 - 博客频道 - CSDN.NET...
查看>>
Javascript创建对象的7种模式
查看>>
Shell工作笔记01
查看>>
项目、软件开发过程中版本术语
查看>>
CSS实现背景透明,文字不透明(各浏览器兼容)
查看>>
【转】[大学引导]超级链接、字体颜色、音乐播放公式
查看>>
T-SQL中INSERT、UPDATE
查看>>
Linux下Nginx服务器配置Modsecurity实现Web应用防护系统
查看>>
openSUSE13.2安装ruby和rails
查看>>
python 高级函数
查看>>
F.Cards with Numbers
查看>>
简单入门Buffer
查看>>
OO第四阶段总结
查看>>
javascript总结02
查看>>
创建windows服务
查看>>
HTML5 入门基础
查看>>