0

编写一些处理响应和请求的代码。两者都可以是 XML 的形式,也可以是通过转换和序列化创建的 C# 对象的形式。(这是.NET 2.0)

Response 和 Request 是较大消息类型的基本实现。现在我有 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 文档。我知道这个文档将被映射为一个请求,所以我调用了一个被覆盖的虚拟方法(我认为它很难看)。将映射代码保留在基础中的原因是不重复代码,但我发现我正在做我想通过以下方式避免的确切事情:

获取资格:基类

   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)

4

2 回答 2

3

您可以使用MethodInfo.MakeGenericMethod 方法来避免在调用泛型方法之前检查类型。下面是一个快速使用示例:

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 });
    }
}

请注意,我使用了typeof(DateTime),但在您的情况下,您可以将其替换为typeof(T)以实现所需的松散耦合解决方案。

于 2012-06-05T00:44:18.817 回答
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的专用MapToRequest和方法进行通用化:MapToResponse

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>
{}
于 2012-06-06T02:19:12.003 回答