詬病WCF之一,對已知型別的支援比較弱智(WCF面向介面程式設計)

iDotNetSpace發表於2009-07-23
之所以這樣說是因為如果我們要開發面向藉口程式設計的服務的話,那麼你就比較倒黴了。無論是WCF固有的KnownType特性還是ServiceKnownType,你都會遇到這樣那樣的困難。
如果我們使用KnownType,那麼我們得在父類中無休止的聲名出子類來。每增加一個子類就得在父類中標記一下。這種方法顯然違反了物件導向的原則。
如果使用ServiceKnownType,那就得配置一些東西來標明我們的型別,但是成功的機率小的可憐。
舉個例子:
我們的藉口型別:
namespace Lib
詬病WCF之一,對已知型別的支援比較弱智(WCF面向介面程式設計)
{
    
public interface IData
詬病WCF之一,對已知型別的支援比較弱智(WCF面向介面程式設計)    
{
        
void Save();
    }

}

我們的服務契約
namespace Lib
詬病WCF之一,對已知型別的支援比較弱智(WCF面向介面程式設計)
{
    [ServiceContract]
    
public interface IMyService
詬病WCF之一,對已知型別的支援比較弱智(WCF面向介面程式設計)    
{
        [OperationContract()]
        
void Add(IData data);
    }

}

我們的服務實現類:
namespace Lib
詬病WCF之一,對已知型別的支援比較弱智(WCF面向介面程式設計)
{
    
public class MyService:IMyService
詬病WCF之一,對已知型別的支援比較弱智(WCF面向介面程式設計)    
{
詬病WCF之一,對已知型別的支援比較弱智(WCF面向介面程式設計)        
IMyService 成員
    }

}

如果按這樣把服務釋出出去後,客戶端得到的代理類的方法void Add(Object data);
當我們在客戶端實現了IData,自定義自己的資料類的時候就會出錯,比如:
詬病WCF之一,對已知型別的支援比較弱智(WCF面向介面程式設計)
namespace DataLib
詬病WCF之一,對已知型別的支援比較弱智(WCF面向介面程式設計)
{
    [DataContract]
    [Serializable]
    
public class MyData:IData
詬病WCF之一,對已知型別的支援比較弱智(WCF面向介面程式設計)    
{
        [DataMember]
        
public string Name;
        [DataMember]
        
public int ID;

詬病WCF之一,對已知型別的支援比較弱智(WCF面向介面程式設計)        
IData 成員
    }

}
當我們把MyData的型別向伺服器傳輸的時候就會報出序列化出錯之類的錯誤,我們按照ServiceKnownType進行配置之後也達不到預想的效果,KnownType又不符合物件導向的方法。
那該怎麼辦?
既然WCF不知道如何序列化我們的MyData類,那我們就幫它序列化好了,那麼我們需要改造一下伺服器端的程式碼,改完之後如下:
改造後的服務契約
namespace Lib
詬病WCF之一,對已知型別的支援比較弱智(WCF面向介面程式設計)
{
    [ServiceContract]
    
public interface IMyService
詬病WCF之一,對已知型別的支援比較弱智(WCF面向介面程式設計)    
{
        [OperationContract()]
        
void Add(byte[] data);
    }

}

詬病WCF之一,對已知型別的支援比較弱智(WCF面向介面程式設計)
改造後的服務實現類:
namespace Lib
詬病WCF之一,對已知型別的支援比較弱智(WCF面向介面程式設計)
{
    
public class MyService:IMyService
詬病WCF之一,對已知型別的支援比較弱智(WCF面向介面程式設計)    
{
詬病WCF之一,對已知型別的支援比較弱智(WCF面向介面程式設計)        
IMyService 成員
    }

}

詬病WCF之一,對已知型別的支援比較弱智(WCF面向介面程式設計)
改造後的MyData:
namespace DataLib
詬病WCF之一,對已知型別的支援比較弱智(WCF面向介面程式設計)
{
    [Serializable]
    
public class MyData:IData
詬病WCF之一,對已知型別的支援比較弱智(WCF面向介面程式設計)    
{
詬病WCF之一,對已知型別的支援比較弱智(WCF面向介面程式設計)        
public string Name{Get;Set;}
詬病WCF之一,對已知型別的支援比較弱智(WCF面向介面程式設計)        
public int ID{Get;Set;}

詬病WCF之一,對已知型別的支援比較弱智(WCF面向介面程式設計)        
IData 成員
    }

}
這樣,客戶端在向伺服器傳輸MyData型別的引數的時候已經是byte[] data的了,也就是我們得自己把我們的data序列化成byte[],傳輸的伺服器上,然後在伺服器上反序列化得到我們的
MyData,當然這個MyData是IData型別的,那麼我們就可以呼叫IData的Save()方法了,這樣就實現了,面向藉口程式設計了。
當然得把我們的MyData所在的類庫生成的dll拷貝到伺服器一份,不用加任何配置,一定要保證這個dll和客戶端的版本始終一樣。
這是我暫時想到的思路,希望會對大家有所幫助。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/12639172/viewspace-609982/,如需轉載,請註明出處,否則將追究法律責任。

相關文章