對Castle Windsor的Resolve方法的解析時new對象的探討

來源:互聯網
上載者:User

標籤:測試   png   函數   建立   註冊   imp   env   .sh   back   

依賴注入架構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對象的探討

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.