標籤:測試 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對象的探討