Spring.NET學習筆記10——方法的注入(基礎篇)

來源:互聯網
上載者:User

多數使用者都會將容器中的大部分對象布署為singleton模式。當一個singleton對象需要和另一個singleton對象協作,或者一個非singleton對象需要和另一個非singleson對象協作時,Spring.NET都能很好的處理它們的依賴關係。但是,如果對象的生存周期不同,就可能會產生問題。例如,假設一個singleton對象A要使用一個非singleton(原型)對象B,A中的每個方法都會用到B的新執行個體。由於A是singleton對象,容器只有會建立它一次,也就是說只有一次給A的屬性賦值的機會,所以不可能在每次A需要的時候都給它注入一個新的B。

有一種解決的辦法有點違背控制反轉原則:類A可以通過實現IObjectFactoryAware{
tagshow(event)
}">介面來擷取容器的引用,並調用GetObject("B")在每次需要的時候從容器中請求一個(新的)對象B。但這並不是一個很好的解決方案,因為客戶代碼此時必須要和Spring.NET發生緊耦合。

通過方法注入,我們可以用更優雅的方式解決類似的問題。(摘自Spring.NET中文手冊)

  一、查詢方法注入

  Spring.NET可以動態覆蓋對象的抽象方法或虛方法,並且可以在容器內尋找已命名物件,查詢方法注入就利用了這些功能。個人感覺查詢方法注入類似抽象工廠,為之不同的是,可以不用寫抽象的實現代碼,通過{
tagshow(event)
}">設定檔動態切換{
tagshow(event)
}">組件。
  在lookup-method節點配置name和object屬性

  實現代碼如下:

  1.       <!--查詢方法-->
  2.       <object id="personDao" type="SpringNet_MethodDi.PersonDao, SpringNet_MethodDi" singleton="false"/>
  3.       <object id="objectFactory" type="SpringNet_MethodDi.ObjectFactory, SpringNet_MethodDi">
  4.         <lookup-method name="CreatePersonDao" object="personDao"/>
  5.       </object>

複製代碼

LookupMethod

  1.     //注意,可以直接在配置中定義這個類的對象
  2.     public abstract class ObjectFactory 
  3.     {
  4.         //或者可以是一個虛方法   
  5.         public abstract PersonDao CreatePersonDao();   
  6.     }
  7.     public class PersonDao
  8.     {
  9.         public void Save()
  10.         {
  11.             Console.WriteLine("儲存資料");
  12.         }
  13.     }

複製代碼

  二、替換任意方法

  替換任意方法在項目中使用的很少,實現方法也比較複雜。至於Spring.NET為什麼使用替換任意方法,我還不是很清楚,如果有知道使用情境的朋友可以給我留言。我個人認為其用途是:實現非衍生類別方法的重寫或在IoC架構中簡易的AOP攔截(這一點又不確定,以後我會寫AOP方面的部落格)。

  首先繼承IMethodReplacer介面並實現Implement方法,object[] arguments為傳入的參數。其次在replaced-method節點配置name和replacer屬性,和增加arg-type節點且配置傳回型別match屬性

  代碼如下:

  1.       <!--替換方法-->
  2.       <object id="userDao" type="SpringNet_MethodDi.UserDao, SpringNet_MethodDi">
  3.         <replaced-method name="GetValue" replacer="replaceValue">
  4.           <arg-type match="String"/>
  5.         </replaced-method>
  6.       </object>
  7.       <object id="replaceValue" type="SpringNet_MethodDi.ReplaceValue, SpringNet_MethodDi"/>

複製代碼

ReplacedMethod

  1.     public class UserDao
  2.     {
  3.         //虛方法
  4.         public virtual string GetValue(string input)
  5.         {
  6.             return null;
  7.         }
  8.     }
  9.     //實現IMethodReplacer介面
  10.     public class ReplaceValue : IMethodReplacer
  11.     {
  12.         public object Implement(object target, MethodInfo method, object[] arguments)
  13.         {
  14.             string value = (string)arguments[0];
  15.             return "擷取到:" + value;
  16.         }
  17.     }

複製代碼三、事件注入

  在Spring.NET的IoC架構中,除了提供方法注入以外,還提供事件的注入。通過事件的注入,可以使架構體系的耦合降到最低。(參考 clingingboy的 Spring.NET學習筆記(3)-註冊事件注入)

  在listener節點處配置event和method屬性指明事件名和綁定的方法,並增加ref節點設定object屬性來指明調用哪個IoC容器物件。

  實現代碼:

  1.       <!--事件注入-->
  2.       <object id="men" type="SpringNet_MethodDi.Men, SpringNet_MethodDi">
  3.         <listener event="OpenTheDoor" method="OpenThisDoor">
  4.           <ref object="door"/>
  5.         </listener>
  6.       </object>         
  7.       <object id="door" type="SpringNet_MethodDi.Door, SpringNet_MethodDi" />

複製代碼

Listener

  1.     //先定義一個委託
  2.     public delegate string OpenHandler(string arg);

  3.     public class Door
  4.     {
  5.         public event OpenHandler OpenTheDoor;

  6.         public void OnOpen(string arg)
  7.         {
  8.             //呼叫事件
  9.             if (OpenTheDoor != null)
  10.             {
  11.                 Console.WriteLine(OpenTheDoor(arg));
  12.             }
  13.         }
  14.     }

  15.     public class Men
  16.     {
  17.         public string OpenThisDoor(string arg)
  18.         {
  19.             return "參數是:" + arg;
  20.         }
  21.     }

複製代碼

調用部分代碼:

Program

  1. class Program
  2.     {
  3.         static void Main(string[] args)
  4.         {
  5.             IApplicationContext ctx = ContextRegistry.GetContext();

  6.             Console.WriteLine("查詢方法");
  7.             ObjectFactory factory = (ObjectFactory)ctx.GetObject("objectFactory");
  8.             factory.CreatePersonDao().Save();
  9.             Console.WriteLine();

  10.             Console.WriteLine("替換方法");
  11.             UserDao dao = (UserDao)ctx.GetObject("userDao");
  12.             Console.WriteLine(dao.GetValue("Liu Dong"));
  13.             Console.WriteLine();

  14.             Console.WriteLine("事件註冊");
  15.             Door door = (Door)ctx.GetObject("door");
  16.             door.OnOpen("Opening!");
  17.             Console.WriteLine();

  18.             Console.ReadLine();
  19.         }
  20.     }

複製代碼

輸入效果:

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.