16

I have following layers in my solution:

  1. App.Domain
  2. App.Service
  3. App.Core (maybe you call this one App.DataLayer)
  4. App.Web

Software design pattern is not my question, I have following Model in Domain

public class Foo {
    public int Id {get;set;}
    public int Name {get;set;}
    public int Value {get;set;}
}

I want to use this model on the view (for example home page) AND I want to use Id, Name & Value, so if I want to create ViewModel, I'll add following:

public class FooViewModel {
    public int Id {get;set;}
    public int Name {get;set;}
    public int Value {get;set;}
}

So, is that good idea? or just use Foo instead of FooViewModel?

  • I'm not sure I understand this. Isn't the Model usually passed to the View? Why exactly do you need to recreate the fields of the Model in the View? If separation of concerns is a goal of MVC, under what circumstances would one want to do the same thing with Model and View? If ViewModel is both, why not by extending / composing both Model and View? – null Aug 9 '15 at 23:14
  • please read my comments on @svidgen's answer – Mehdi Dehghani Aug 10 '15 at 6:44
  • I have a related issue - where validation (required attribute) on the models (and in the database) state certain values must be entered - but in views, those values don't need to be - so I am forced to copy some fields from the models int the view model - rather than referencing the model directly. However on reflection this probably is fine and indeed doesn't violate DRY as they are for different purposes (not too badly anyway). – niico Sep 21 '16 at 21:11
20

This may look like a violation of the DRY rule initially, but I'd argue that "similar, and even identical, code" isn't necessarily "repetition" if it does something different or is able to change independently. And in the case of view models, the code is defining what the "client" sees, not necessarily the entities and operations the business talks about. So, you're often revealing models to the client or interface that are sort of "incidentally identical." You may change either the business rules and terms or the end user terminology independently of each other.

So, I'd turn the question back on you. If the domain changes, is it acceptable for the "version 1" clients to continue using the old interfaces? Will you ever reveal terms or operations in the interface that aren't part of the "core business rules?" And vice versa?

Those sort of questions in mind, if your view's "function" is strictly to reveal the underlying domain model, yes, this seems like it violates the DRY rule.

Also bear in mind, exposing a view that changes more naturally with model changes can also be accomplished in some languages with member attributes and reflection. (Or with less repetition through other feats of cleverness... But, "cleverness" often fails to justify the repetition it spares you.)

  • Nice mentioned notes (vote up for this), as I said as comment on previous answer, I'm talking about general purpose, imaging, maybe some days later, I decided to add new field/property to Foo, so if I used Foo as ViewModel too, client will get new property too, so what about if this new one was some security field, (maybe true/false for permission, or something like that), what should I do? – Mehdi Dehghani Aug 9 '15 at 17:09
  • @mehdi you'll need to be more specific about what field you're thinking of adding and why you think it does or doesn't belong in the view. Or in general, what the concern is there. – svidgen Aug 9 '15 at 17:12
  • @mehdi to be clear, if you're worried about end users changing a security value, your domain simply shouldn't allow users to save things they're not authorized to save – svidgen Aug 9 '15 at 17:13
  • Why we using ViewModels? there is some reasons, as we know, one of them is for security, for example, in User edit form, we don't need to pass IsAdmin field to the client, for keeping this field secure, so this is what I'm worry about. sorry for my bad English. – Mehdi Dehghani Aug 9 '15 at 17:15
  • 1
    Put another way, I think the original question is a full question. The question you're trying to figure out in the comments here is another full question. And comments aren't a good way to get good, quality answers. – svidgen Aug 10 '15 at 17:20
2

I would have a view model that contained just one property, a Foo instance. That way, you are not violating DRY according to any definition of it, if Foo changes, your view model automatically sees the change, and you leave yourself free of a direct tie of the view model to the model.

If tomorrow there is a need for the view to show something else as well as the Foo, you can just add a new property, and your view model's intent will still be clear, it contains a Foo and something else, you won't have a mixture of properties from Foo with unrelated other properties.

I wouldn't think of your view model as a FooViewModel, I would think of it in terms of what the view is supposed to display. If it just displays one Foo, then the view model contains one property, a Foo.

Not sure if I explained that clearly. If not, let me know and I'll try and reword it when I'm awake!

-2

I would say using FooViewModel in this way violates the DRY principal. When you need to make a change to Foo you also have to make a change to FooViewModel. I think you would be better served simply using Foo as the model for your view. I would consider a view model if you need to display things from Foo and something other things. For example, say you need to render some information from Foo and also from Bar.

  • Please tell me, if I decided to add another field/property to the Foo, so because I used Foo as ViewModel too, so I have to pass this new field to the view too, I think this is not really good deal, what do you think? – Mehdi Dehghani Aug 9 '15 at 15:35
  • I don't see anything wrong with having the View use only a subset of the data exposed by the model. I think the greater foul is the coupling between Foo and FooViewModel. Generally, it is not a good idea to have to modify multiple files for a single logical change. – zero_dev Aug 9 '15 at 15:44
  • What about If that added field was a security field, such as some true/false value for permission or something like that. – Mehdi Dehghani Aug 9 '15 at 15:47
  • You don't have to expose such fields in the View itself, but you should still make sure the rest of your code does not allow the user to change their security level, just in case a malicious user tries to POST such a change. – Graham Aug 10 '15 at 12:31
  • Sounds like it would be open to mass assignment attacks – James Aug 10 '15 at 14:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.