0

I am learning to apply DIC to MVC project. So, I have sketched this DDD-ish DIC-ready-ish layout to my best understanding. I have read many blogs articles wikis for the last few days. However, I am not confident about implementing it correctly. Could you please demonstrate to me how to put them into DIC the proper way? I prefer Ninject or Windsor after all the readings, but anyDIC will do as long as I can get the correct idea how to do it.

Web controller...

public class AccountBriefingController {
    //create
    private IAccountServices accountServices { get; set; }
    public AccountBriefingController(IAccountServices accsrv)
        accountServices = accsrv;
    }   
    //do work
    public ActionResult AccountBriefing(string userid, int days) {
        //get days of transaction records for this user
        BriefingViewModel model = AccountServices.GetBriefing(userid, days);
        return View(model);
    }
}

View model ...

public class BriefingViewModel {
    //from user repository
    public string UserId { get; set; }
    public string AccountNumber {get; set;}
    public string FirstName { get; set; }
    public string LastName { get; set; } 
    //from account repository
    public string Credits { get; set; } 
    public List<string> Transactions { get; set; }
}

Service layer ...

public interface IAccountServices {
    BriefingViewModel GetBriefing();
}

public class AccountServices {
    //create
    private IUserRepository userRepo {get; set;}
    private IAccountRepository accRepo {get; set;}
    public AccountServices(UserRepository ur, AccountRepository ar) {
        userRepo = ur;
        accRepo = ar;
    }
    //do work
    public BriefingViewModel GetBriefing(string userid, int days) {
        var model = new BriefingViewModel(); //<---is that okay to new a model here??
        var user = userRepo.GetUser(userid);
        if(user != null) {
            model.UserId = userid;
            model.AccountNumber = user.AccountNumber;
            model.FirstName = user.FirstName;
            model.LastName = user.LastName;
            //account records
            model.Credits = accRepo.GetUserCredits(userid); 
            model.Transactions = accRepo.GetUserTransactions(userid, days);
        }
        return model;
    }
}

Domain layer and data models...

public interface IUserRepository {
    UserDataModel GetUser(userid);
}
public interface IAccountRepository {
    List<string> GetUserTransactions(userid, days);
    int GetUserCredits(userid);
}
// Entity Framework DBContext goes under here

Please point out if my implementation is wrong, e.g.I can feel in AccountServices->GetBriefing -> new BriefingViewModel() seems wrong to me, but I don't know how to fit the stud into DIC?

Thank you very much for your help!

Krzysztof Kozmic
  • 27,267
  • 12
  • 73
  • 115
Tom
  • 15,781
  • 14
  • 69
  • 111

1 Answers1

2

I guess there is 2 questions here. First, how to set up the a customer Dependency Resolver with either Ninject or Windsor. Second, whether the dependencies are modelled correctly.

I'm going to point you at a couple of links for the first question because it has been answered quite well here on SO and in blog posts:

Ninject

Windsor

On the second question, IMHO, I don't think that IAccountServices should necessary know about view models. I like to keep my dependencies aligned in one direction. So it would be the AccountBriefingController's job to convert a User (or a new model object named Briefing) to a BriefingViewModel. This takes care of the question of whether to new-up a BriefingViewModel. However, you will have to map a User to a BriefingViewModel in the controller (and this will require you to create a new instance). Otherwise, the dependencies look OK to me.

So I would change the GetBriefing to this:

public User GetBriefing(string userid, int days) {
        var user = userRepo.GetUser(userid);
        if(user != null) {
            return user;
        }
        throw new CustomException();  //if this makes sense
    }

Then, you would do the mapping in the controller.

Community
  • 1
  • 1
Davin Tryon
  • 66,517
  • 15
  • 143
  • 132
  • Thank you very much. I am getting the idea now :D – Tom Jul 09 '12 at 10:19
  • 1
    @Tom Glad to help. I was thinking a bit more about this. I think I would opt to return a new `Briefing` object so that you could still look up the Credits and Transactions. Then map the `Briefing` to `BriefingViewModel`. Then, you have a clean separation. – Davin Tryon Jul 09 '12 at 11:16
  • Thanks for pointing out. I understood your idea. Actually, my original full size plan was app.website -> view models -> app.services -> domain.services -> domain.data models and repositories... where domain.services organise the data models, app.services layer maps them to view models ... or a fatter view model can maintain data models in it and manage them... then i think the whole thing is not so DRY, and I came up with a 2nd plan. – Tom Jul 10 '12 at 08:46
  • Data layer: DbContext generates the dataModels for me automatically, so I create partial buddy classes and wrap then with validation attributes. Services layer: a typical pattern of the functions here is like this, a function, public ErrorMessageIfAny DoServiceJob(param1, param2..., out datamodel1, out datamodel2...) so it spits out data models to the web layer. – Tom Jul 10 '12 at 08:56
  • basic idea of my 2nd plan is to remove the view models (heresy! i know...), hence remove the needs of DataModel->ViewModel mapping. I am trying to use data models directly on a view. We map sql dataviews and sql sp/func with asp.net in the good old days anyway? flatter that way. – Tom Jul 10 '12 at 08:59
  • 1
    That sounds like a good way forward for what you need. You might find that a view model will help in some cases and you can then add it when you need it. In my experience, view models help because they can align the model to what is needed for binding. This can be very helpful when binding more complex structures. – Davin Tryon Jul 10 '12 at 10:58
  • Here is why I don't quite get the ViewModels. Matching a few db-to-memory-models into another memory-model by code, 2-way view & save, seems like a lot of pain for most of the time. Could you please show me a quick case in what kind of complex structure we could get more benefits out of it? Would you use a mix of some data models some view models in the web layer or convert everything into view models for a clear alignment? – Tom Jul 10 '12 at 13:40
  • 1
    One example would be a drop down list of bank accounts (let's say). On your business model `BankAccount` might include more than 30 fields (with complex relationships to other entities). However, to bind the the drop down list you just need the primary key and the display name. So it doesn't make sense to send the big object to the rendering engine. – Davin Tryon Jul 10 '12 at 14:33
  • Thanks for the example. However, the case would not happen. dropdownlist result set would notmally be done by a sql dataview, or say we want a total transaction amount, sql func will only give back a number, or necessary columns in the dataview for dropdownlist, and the result set is mapped to the data-model. Of course that is a DB first approach. If it was a code first approach, we may have a simpler DB without that many sp/func. So, my case only applies for a fat sql approach. But yeah, I fail to see how MVC needs a view-model layer support. – Tom Jul 10 '12 at 15:19