Tuesday, December 4, 2007

Object to DTO and back in an efficient manner

Reading Oren's post about converting an object to a DTO I got to thinking. Why do all that work of reassigning a bunch of properties if you can avoid it? The DTO is probably going to be serialized before being sent over the wire and only public properties are serialized; it doesn't make much sense to me to run a transform which would need to run at least 1 delegate (1 for every property to property transform), instantiate a new DTO, instantiate a List, instantiate an enumerator and enumerate over a list and instantiate a transformation class just to call a single method on it. It seems to me that most of this extra work can be avoided.

Here is a naive approach I would consider before running to lists of lambda expressions:

internal class DbOrder {
    public string Name;
    public int Id;
}
 
public class Order {
    private DbOrder _dbOrder;
 
    private Order(DbOrder o) {
        _dbOrder = o;
    }
 
    internal DbOrder DbOrder {
        get {
            if (_dbOrder == null) {
                _dbOrder = new DbOrder();
            }
            return _dbOrder;
        }
    }
 
    public string Name {
        get { return DbOrder.Name; }
        set { DbOrder.Name = value; }
    }
 
    public int Id {
        get { return DbOrder.Id; }
        set { DbOrder.Id = value; }
    }
 
    public static explicit operator Order(OrderDTO obj) {
        return new Order(obj.DbOrder);
    }
}
 
public class OrderDTO {
    private DbOrder _dbOrder;
 
    private OrderDTO(DbOrder o) {
        _dbOrder = o;
    }
 
    internal DbOrder DbOrder {
        get {
            if (_dbOrder == null) {
                _dbOrder = new DbOrder();
            }
            return _dbOrder;
        }
    }
 
    public string CustomerName {
        get { return DbOrder.Name; }
        set { DbOrder.Name = value; }
    }
 
    public int ID {
        get { return DbOrder.Id; }
        set { DbOrder.Id = value; }
    }
 
    public static explicit operator OrderDTO(Order obj) {
        return new OrderDTO(obj.DbOrder);
    }
}


The reason I would consider doing this this way is because both the Business class and the DTO class are nothing more than proxies to the data. Since this is the case, a Proxy pattern seems to me to be the best way to treat them.

No comments: