5

I'm sure someone has asked this before, but I'm struggling to find where.

I'm using Ninject to remove dependencies from my controllers, along with a repository design pattern.

As I understand it, one of the benefits of this approach is that I can easily whip apart my repositories and domain entities and use another assembly should I so wish. Consequently I've kept my domain entities and repositories in external assemblies and can mock all my dependencies from interfaces.

It seems that while I can use interfaces to refer to my domain entities in most places I must use references to my concrete classes when it comes to model binding. I've read that this is to do with serialization which I understand, but is the only way to avoid referring to domain entities to create separate models?

Anything I can do with Custom Model Binding?

A bit of background: I'm an experienced ASP.net developer, but new to MVC.

Ruben Bartelink
  • 59,778
  • 26
  • 187
  • 249
David
  • 727
  • 1
  • 6
  • 16
  • If there's a question like this out there, it's sure is hard to find. I found yours after a while. Thanks for asking his! – user3590235 Aug 26 '20 at 18:27

3 Answers3

8

View Models should be plain data containers with no logic and therefore shouldn't have any dependencies at all. Instead inject the repositories to your controller and have it assign the required data from the repository to the appropriate property of your view model.

Remo Gloor
  • 32,665
  • 4
  • 68
  • 98
  • +1 and here's why: http://stackoverflow.com/questions/4835046/why-not-use-an-ioc-container-to-resolve-dependencies-for-entities-business-objec/4836790#4836790 – Mark Seemann Nov 08 '11 at 11:16
  • Personally I think you should have an application service layer between presentation and data layer and the service should be injected into the controller, but I guess that's a question of preference. – autonomatt Nov 08 '11 at 11:42
  • @autonomatt Sure that is even better and I would do it this way myself. But the question was mainly about injection of repositories into view models and not how to layer applications properly. – Remo Gloor Nov 08 '11 at 11:59
  • @Remo - it's true the data container would have no dependencies, but the controller becomes dependent on the data container if not using an interface. I get that that might be a necessary evil though – David Nov 10 '11 at 11:10
  • @autonomatt - if you were to use a 3 tier architecture, do you think the model generally be an object from the application layer? – David Nov 10 '11 at 11:12
5

The major advantage of using a dependency injection framework is IoC (Inversion of Control):

  • loosely coupling
  • more flexibility
  • easier testing

So what one usually does is to inject repositories through their interfaces like

public class MyController : Controller
{
    private IPersonRepository personRepo;

    public MyController(IPersonRepository personRepo)
    { 
        this.personRepo = personRepo;
    }
    ...
}

During testing this allows to easily inject my mock repository which returns exactly those values I want to test.

Injecting domain entities doesn't make that much sense as they are more tightly linked with the functionality in the specific class/controller and thus abstracting them further would just be an overhead rather than being a benefit. Instead, if you want to decouple your actual entity model from the controller you might take a look at the MVVM pattern, creating specialized "ViewModels".

Just think in terms of testability of your controller: "What would I want to mock out to unit test it?"

  • DB accesses -> the repository
  • External dependencies -> other BL classes, WS calls etc.

I wouldn't include domain entities here as they're normally just a data container.

Juri
  • 32,424
  • 20
  • 102
  • 136
  • Really useful thanks. I've a bit anal, so what to abstract everything but from the sounds of it I'm going a bit far. – David Nov 08 '11 at 16:27
  • @David Overengineering is quite easy to fall in :) You just need to continuously ask yourself if it makes sense or if it just complicates things unnecessarily. Personally I try to architect my solutions s.t. they're easily testable. In that way the design usually gets nice as well. – Juri Nov 08 '11 at 22:10
1

Some more details would help. A bit of code perhaps?

To start with, you should avoid injecting dependencies into domain entities, but rather use domain services.

Some more info here.

Edit 001:

I think we should clarify our terminology. There is the domain layer with all you domain entities, e.g. product, category etc. Then there's the Data Layer with your repositories that hydrate your domain entities and then you have a Service Layer with you application services that talks to the data layer.

Finally you have a presentation layer with your views and controllers. The Controllers talk to you Aplication Service Layer. So a Product Controller talks to a Catalogue Service (e.g. GetProductBySku). The CatalogueService will have one or more repositories injected into its constructor (IProductRepository, ICategoryRepository etc.). It's quite common in asp.net mvc to have ViewModels too. Put the ViewModels in your Application Service Layer.

So I'm not sure what you mean when you say "models" and "domain enntities" but I hope that clears up the terminology.

autonomatt
  • 4,393
  • 4
  • 27
  • 36
  • I could post some code but there would be pages of it and it's more of an architectural issue. I suppose the main question is; is there a way to supply models through dependency injection? – David Nov 08 '11 at 11:08
  • Thanks for the link BTW. An interesting read, but didn't really answer my question – David Nov 08 '11 at 11:11
  • With regard to domain services, I assume you're referring to things like the Entity Framework. I'm going to use Castle ActiveRecord/ NHibernate for the data layer. Do you think my model should be seperate from my domain entity? – David Nov 08 '11 at 11:15
  • Good choice. I use NHibernate and Castle Windsor. See my editted question for more details. – autonomatt Nov 08 '11 at 11:32