close
文章出處

     我在項目中都使用Spring.net作為IOC容器,今天有遇到了以前曾經出現的一個奇怪的bug,描述如下。

     我配置了GameRoomConfig對象:

 

 <object name="gameRoomConfig" type="GamePlatform.Entity.Runtime.GameRoomConfig,GamePlatform.Entity">
        
<property name="ID" value="3011"/>
        
<property name="GameID" value="DDZ"/>
        
<property name="ListenIP" value="192.168.0.206"/>
        
<property name="ListenPort" value="9090"/>
        
<property name="IP" value="192.168.0.206"/>
        
<property name="Port" value="9090"/>
        
<property name="MaxUserCount" value="500"/>
        
<property name="GPSCallback" ref="serviceForGPSCallback"/>
      
</object>

 

     在IOC容器中,有多個對象都注入了配置的這個gameRoomConfig對象,而這些配置在以前一年多的時間中一直工作良好,今天我重裝系統后,再在VS中啟動這個程序就無法正常運行了,原因在于其它依賴于gameRoomConfig的對象在它們自己的Initialize方法中使用gameRoomConfig時候,gameRoomConfig的各個屬性還未被賦值。也就是說,gameRoomConfig對象還未被正確設置就被其它依賴對象使用了。我為其它依賴對象加上 depends-on="gameRoomConfig" 來作強制檢查也于事無補。

     真是奇怪,在一年多以前就遇到過這個問題,后來不知道是什么原因又莫名其妙的自動好了,現在又出現了。當前我的補救方案是,將gameRoomConfig對象由Singleton模式改為SingleCall模式,這樣每個依賴對象都使用一個獨立的gameRoomConfig對象了。

<object name="gameRoomConfig" type="GamePlatform.Entity.Runtime.GameRoomConfig,GamePlatform.Entity" singleton="false" >

     

     如果大家也有遇到過類似的問題,請告知一下真正的原因,謝謝。

 

     正解:應該是在錯綜復雜的依賴關系中引入了循環依賴,我通過移除一個屬性依賴,使得系統又恢復正常。上面所述的現象看似問題出在gameRoomConfig對象上,實則不然,我斬斷的那個循環依賴鏈似乎與gameRoomConfig對象的關聯不大。

     也就是說,如果依賴關系中出現循環依賴,則會導致循環鏈中的某個對象在其屬性未被賦值前就被其它依賴對象所使用。     

     解決的方案是,斬斷循環依賴,這可以通過引入一個中間的Bridge對象做到,在Bridge對象的Initialize方法中,將兩者的依賴關系動態的建立起來(這就繞過了Spring的對象依賴的靜態檢測)。如橋的Initialize方法示例:

 

    public class GameInitializer
    {  
        
#region GameRoomConfig
        
private GameRoomConfig gameRoomConfig;
        
public GameRoomConfig GameRoomConfig
        {
            
set { gameRoomConfig = value; }
        } 
        
#endregion             

        
#region GPSCallback
        
private IGPSCallback gPSCallback;
        
public IGPSCallback GPSCallback
        {
            
set { gPSCallback = value; }
        } 
        
#endregion

        
public void Initialize()
        {
            
/* 由于GPSCallback對象引入了循環依賴,斬斷它 */
            
this.gameRoomConfig.GPSCallback = this.gPSCallback;         
        }
    }

     

 

 


不含病毒。www.avast.com
arrow
arrow
    全站熱搜

    AutoPoster 發表在 痞客邦 留言(0) 人氣()