Dependency Inject for models
Asked Answered
M

3

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.

Magulac answered 8/11, 2011 at 10:34 Comment(1)
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!Eulogy
A
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.

Azide answered 8/11, 2011 at 11:6 Comment(2)
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.Magulac
@Magulac 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.Azide
S
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.

Slushy answered 8/11, 2011 at 11:11 Comment(5)
+1 and here's why: #4835546Autochthon
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.Habiliment
@Habiliment 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.Slushy
@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 thoughMagulac
@Habiliment - if you were to use a 3 tier architecture, do you think the model generally be an object from the application layer?Magulac
A
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.

Azide answered 8/11, 2011 at 11:6 Comment(2)
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.Magulac
@Magulac 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.Azide
H
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.

Habiliment answered 8/11, 2011 at 11:0 Comment(4)
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?Magulac
Thanks for the link BTW. An interesting read, but didn't really answer my questionMagulac
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?Magulac
Good choice. I use NHibernate and Castle Windsor. See my editted question for more details.Habiliment

© 2022 - 2024 — McMap. All rights reserved.