views:

98

answers:

2

In my continuing journey through ASP.NET MVC, I am now at the point where I need to render an edit/create form for an entity.

My entity consists of enums and a few other models, created in a repository via LINQtoSQL.

What I am struggling with right now is finding a decent way to render the edit/create forms which will contain a few dropdown lists and a number of text fields. I realize this may not be the most user-friendly approach, but it is what I am going with right now :).

I have a repository layer and a business layer. The controllers interface with the service layer.

Is it best to simply create a viewmodel like so?

public class EventFormViewModel
{
    IEventService _eventService;

    public IEvent Event { get; private set; }

    public IEnumerable<EventCampaign> Campaigns { get; private set; }
    public IEnumerable<SelectListItem> Statuses { get; private set; }
    // Other tables/dropdowns go here

    // Constructor
    public EventFormViewModel(IEventService eventService, IEvent ev)
    {
        _eventService = eventService;
        Event = ev;

        // Initialize Collections
        Campaigns = eventService.getCampaigns().ToSelectList(); //extn method maybe?
        Statuses = eventService.getStatus().ToSelectList();  /extn for each table type?
    }

So this will give me a new EventFormViewModel which I'll bind to a view. But is this the best way? I'd essentially be pulling all data back from the database for a few different tables and converting them to an IEnumerable. This doesn't seem overly efficient, but I suppose I could cache the contents of the dropdowns.

Also, if all I have is methods that get data for a dropdown, should I just skip the service layer and go right to the repository?

The last part of my question: For the ToSelectList() extension method, would it be possible to write one method for each table and use it generically even if some tables have different columns ("Id" and "Name" versus "Id" and "CampaignName").

Forgive me if this is too general, I'm just trying to avoid going down a dead-end road - or one that will have a lot of potholes.

A: 

I would say if you're thinking of "skipping" a layer than you're not really ready to use MVC. The whole point of the layers, even when they're thin, is to facilitate unit testing and try to enforce separation of concerns.

As for generic methods, is there some reason you can just use the OOB objects and then extend them (with extension methods) when they fail to meet your needs?

No Refunds No Returns
My favorite part of SO - anonymous down-votes. Maybe one day a comment will be required.
No Refunds No Returns
+1 I like the idea of extending the Data Objects - will give that a go :). I think the "layers" portion is not MVC-exclusive, though I see your point. I put the service layer there for a reason - no matter how simple the call, I shouldn't skip it in theory.
Dan
I don't think you've done yourself any favours with an aggressive tone, but I'll give you +1 cause I think you have a point.
pdr
+1  A: 

I wouldn't provide an IEventService for my view model object. I prefer to think of the view model object as a dumb data transfer object. I would let the controller take care of asking the IEventService for the data and passing it on to the view model.

I'd essentially be pulling all data back from the database for a few different tables and converting them to an IEnumerable

I don't see why this would be inefficient? You obviously shouldn't pull all data from the tables. Perform the filtering and joining you need to do in the database as usual. Put the result in the view model.

Also, if all I have is methods that get data for a dropdown, should I just skip the service layer and go right to the repository?

If your application is very simple, then a service layer may be an unneeded layer of abstraction / indirection. But if your application is just a bit complex (from what you've posted above, I would guess that this is the case), consider what you will by taking a shortcut and going straight to a repository and compare this to what you will win in maintainability and testability if you use a service layer.

The worst thing you could do, would be to go through a service layer only when you feel there is a need for it, and go straight to the repository when the service layer will not be providing any extra logic. Whatever you do, be consistent (which almost always means: go through a service layer, even when your application is simple. It won't stay simple).

Rune
+1 Good stuff, Rune. If anything, it was a "you're not crazy" answer, which I need sometimes :)
Dan
Also, is it better to have a ViewModel constructor that accepts all the data you want it to hold?
Dan
As for the constructor issue, I don't really care much. Sometimes view model objects can have a lot of different properties. In those cases I prefer to use an initialization block (or whatever they are called), you know: new MyObject() { Property1 = value1, ... };
Rune