2012-06-05 17 views
0

編寫一些處理響應和請求的代碼。兩者都可以採用XML形式,並且都可以採用通過轉換和序列化創建的C#對象的形式。 (這是.NET 2.0)任何更好的方法來確定基於T和子類的類型

響應和請求都較大的消息類型的基極實現。現在我有GetEligibility和FindCandidates。在Model.MessageModel類

例中使用如下:

public partial class GetEligibilityResponseMessage : ResponseMessage 

public partial class ResponseMessage : Message 

因爲我不想重複我的地圖功能我已經決定使用泛型來簡化這個過程中,它的工作出很大:

基類代碼

public virtual Model.MessageModel.Message MapToModel<T>(XmlDocument xml) 
    { 
     V3Mapper mapper = new V3Mapper(); 
     Model.MessageModel.Message message = mapper.MapToDomainModel<T>(xml, Environment) as Model.MessageModel.Message; 
     return message; 
    } 

    public virtual XmlDocument MapToXml<T>(Model.MessageModel.Message message) 
    { 
     V3Mapper mapper = new V3Mapper(); 
     XmlDocument xml= mapper.MapToV3Message<T>(message, Environment); 
     return xml; 
    } 

當我的代碼第一次調用,它有一個XML documen噸。我知道這個文檔將被映射爲一個請求,所以我調用一個被覆蓋的虛擬方法(我認爲它很醜)。保持映射代碼在基本的原因是爲了不重複的代碼,但是我發現我做我想要避免以下的確切的事情:

GetEligibility:BaseClass的

public override Model.MessageModel.Message MapToModel<T>(XmlDocument xml) 
    { 
     if(typeof(T).IsAssignableFrom(typeof(GetEligibilityResponseMessage))) 
     { 
      return base.MapToModel<GetEligibilityResponseMessage>(xml); 
     } 
     else if (typeof(T).IsAssignableFrom(typeof(GetEligibilityRequestMessage))) 
     { 
      return base.MapToModel<GetEligibilityRequestMessage>(xml); 
     } 
     return null;//because this is a quick code snippet 
    } 

是有一個更優雅的方式來做到這一點?我總是知道我是否正在處理響應或請求。我想讓功能開放,所以它不是太緊密耦合,但同時它具有功能和速度。

這將通過多種不同的消息類型來實現,我真的很討厭編碼的複製/粘貼式的,這樣一個優雅的解決方案將是巨大的,但我不知道是否有一個。 (.NET 2.0)

+0

我的建議,不要那樣做。這隻會導致代碼混淆。 –

+0

而不是幾乎相同的2個函數複製/粘貼在10個不同的類?不是我的一杯茶。我不是最後一個代碼塊的粉絲,因此詢問關於它 –

+0

的原因只要沒有從'GetEligibilityResponseMessage'和'GetEligibilityRequestMessage'派生類,你被覆蓋的'MapToModel'相當於基地之一,與類型檢查異常。那麼重寫'MapToModel'方法有什麼意義呢?僅僅用於類型檢查? –

回答

3

可以使用MethodInfo.MakeGenericMethod Method以避免調用您的泛型方法之前檢查類型。下面是一個快速的使用例子:我用的typeof(DateTime的),但在你的情況下,你可以替換由的typeof(T)達到理想的鬆耦合解決方案

class Program 
{ 
    public static void Generic<T>(T toDisplay) 
    { 
     Console.WriteLine("\r\nHere it is: {0}", toDisplay); 
    } 

    static void Main(string[] args) 
    { 
     MethodInfo mi = typeof(Program).GetMethod("Generic"); 
     MethodInfo miConstructed = mi.MakeGenericMethod(typeof(DateTime)); 

     DateTime now = DateTime.Now; 
     miConstructed.Invoke(null, new object[] { now }); 
    } 
} 

通知。

0

如果你只是想驗證請求和響應類型,你可以有你的基類知道這件事:

public class BaseClass 
{ 
    private readonly Type _requestType; 
    private readonly Type _responseType; 

    protected BaseClass(Type requestType, Type responseType) 
    { 
     _requestType = requestType; 
     _responseType = responseType; 
    } 

    public T MapToModel<T>(XmlDocument xml) 
    { 
     if (typeof(T) != _requestType && typeof(T) != _responseType) 
      throw new InvalidOperationException("Invalid type"); 

     var mapper = new V3Mapper(); 
     return mapper.MapToDomainModel<T>(xml, Environment); 
    } 
} 

public GetEligibility : BaseClass 
{ 
    public GetEligibility() 
     : base(typeof(GetEligibilityRequestMessage), typeof(GetEligibilityResponseMessage)) 
    {} 
} 

你甚至可以更進一步,使BaseClass通用,專用MapToRequestMapToResponse知道回報的方法:

public class BaseClass<TRequest, TResponse> 
    where TRequest:RequestMessage, 
      TResponse:ResponseMessage 
{ 
    public TRequest MapToRequest(XmlDocument xml) 
    { return MapToModel<TRequest>(xml); } 

    public TResponse MapToResponse(XmlDocument xml) 
    { return MapToModel<TResponse>(xml); } 

    private T MapToModel<T>(XmlDocument xml) 
    { 
     var mapper = new V3Mapper(); 
     return mapper.MapToDomainModel<T>(xml, Environment);   
    } 
} 

public GetEligibility : BaseClass<GetEligibilityRequestMessage, GetEligibilityResponseMessage> 
{} 
相關問題