nhibernate - Strategies for DRY when using ViewModels instead of Entities -
a lot of our pages use custom view models cut versions of nhibernate-mapped entities.
when have global set of entities, reusing small pieces of entity-centric business logic straightforward logic can added entities. however, once have view-specific view models, becomes harder.
here contrived example:
// entity public class sale : entity { public guid id { get; set; } public decimal tax { get; set; } public decimal saleprice { get; set; } public int totalprice { { return tax + saleprice; } } ... more properties ... } // view model public class saleview { public guid id { get; set; } public decimal tax { get; set; } public decimal saleprice { get; set; } } public class controller { public action viewsale(guid id) { return session.query<sale>() .where(x => x.id == id) .select(x => new saleview { id = x.id, tax = x.tax, saleprice = x.saleprice }); } }
in example, strategies use reuse "totalprice" calculation performed in entity?
you make "totalprice" static method somewhere, , have accept tax , sale price parameters, can lead quite ugly, inflexible code, particularly number of properties , relationship between properties grows. create seperate "totalpricecalculator" class, deal viewmodel need accept interface both entity , view model implement. lead proliferation of duplicated code, have write out each property 3 times. else can done?
you define total price policy, can inject in entity , viewmodel. fact inject total price policy makes more flexible. implement other policies. thing this:
public interface itotalpricepolicy { decimal totalprice(decimal tax, decimal salesprice); } public class totalpricepolicy : itotalpricepolicy { public decimal totalprice(decimal tax, decimal salesprice) { return tax + salesprice; } } public class sale : entity { public guid id { get; set; } public decimal tax { get; set; } public decimal saleprice { get; set; } public decimal totalprice(itotalpricepolicy totalpricepolicy) { return totalpricepolicy.totalprice(tax, saleprice); } } public class saleviewmodel { private readonly itotalpricepolicy _totalpricepolicy; public saleviewmodel(itotalpricepolicy totalpricepolicy) { _totalpricepolicy = totalpricepolicy; } public guid id { get; set; } public decimal tax { get; set; } public decimal saleprice { { return _totalpricepolicy.totalprice(tax, saleprice); } } } public class homecontroller : controller { private readonly itotalpricepolicy _totalpricepolicy; public homecontroller(itotalpricepolicy totalpricepolicy) { _totalpricepolicy = totalpricepolicy; } public action viewsale(guid id) { return session.query<sale>() .where(x => x.id == id) .select(x => new saleview(_totalpricepolicy) { id = x.id, tax = x.tax }); } }
Comments
Post a Comment