对Castle Windsor的Resolve方法的解析时new对象的探讨

时间:2022-01-03 06:07:27

依赖注入框架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(); } }

测试结果: