程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> 對Castle Windsor的Resolve方法的解析時new對象的探討,windsorresolve

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

編輯:C#入門知識

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


依賴注入框架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先調用參數個數多且參數通過依賴注入的構造函數,如果參數個數相同的構造函數有多個,則按參數類型名稱(這個名稱應該是完全限定名,沒有測試)順序,調用第一個,如果不存在這樣的構造函數,則優先調用參數個數多且具有默認值的構造函數.

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved