Dependency Inject for models - asp.net-mvc

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.

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.

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.

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.

Related

Service layer and project structure in ASP.NET MVC 5 without repository and UoW patterns

I'd like to create a good app in ASP.NET MVC 5 using EF 6 Code first concept. I want it to be well-designed i.e. having generally speaking: Presentation, Logic and Data layers separated. I want it to be testable :)
Here's my idea and some issues related with creating application
Presentation layer: It's my whole MVC - view models(not models), views, controllers
I believe that's validation should be done somewhere else (in my opinion - it's a part of business logic) but it's quite convenient to use attributes from the DataAnnotations namespace in ViewModelds and check validation in controller.
Logic layer: Services - classes with their interfaces to rule business logic.
I put there functions like: AddNewPerson(PersonViewModel Person), SendMessageToPerson(...).
They will use DB context to make their actions (there's a chance that not all of them will be relying on context). There's a direct connection between service and db - I mean the service class have reference do context.
Where should I do mapping between ViewModel and Model? I've heard that service is a bad place for it - so maybe in controllers. I've heard that service should do the work related with db exclusively.
Is it right? Is my picture of service layer is good?
Data layer: I've read about Repository and UoW patterns a lot. There're some articles which suggest that EF6 implements these two things. I don't want to create extra code if there's no need for such a behavior. The question is: am i right to assume that i don't need them?
Here's my flow:
View<->Controllers(using ViewModels)<->Services(using Models)<->DB.
**I'm gonna use DI in my project.
What do you think about my project structure?
There is no reason to use a Unit of Work pattern with Entity Framework if you have no need to create a generic data access mechanism. You would only do this if you were:
using a data access technology that did not natively support a Unit of work pattern (EF does)
Wanted to be able to swap out data providers sometime in the future.. however, this is not as easy as it might seem as it's very hard NOT to introduce dependencies on specific data technologies even when using an Unit of Work (maybe even BECAUSE you are)... or
You need to have a way of unifying disparate data sources into an atomic transaction.
If none of those are the case, you most likely don't need a custom Unit of Work. A Repository, on the other hand can be useful... but with EF6 many of the benefits of a Repository are also available since EF6 provides mocking interfaces for testing. Regardless, stay away from a generic repository unless it's simply an implementation detail of your concrete repositories. Exposing generic repositories to your other layers is a huge abstraction leak...
I always use a Repository/Service/Façade pattern though to create a separation between my data and business (and UI and business for that matter) layers. It provides a convenient way to mock without having to mock your data access itself and it decouples your logic from the specific that are introduced by the Linq layer used by EF (Linq is relatively generic, but there are things that are specific to EF), a façade/repository/server interface decouples that).
In general, you're on the right path... However, let me point out that using Data Attributes on your view models is a good thing. This centralizes your validation on your model, rather than making you put validation logic all over the place.
You're correct that you need validation in your business logic as well, but your mistake is the assumption that you should only have it on the business logic. You need validation at all layers of your application.. And in particular, your UI validation may have different requirements than your business logic validation.
For instance, you may implement creating a new account as a multi-step wizard in your UI, this would require different validation than your business layer because each step has only a subset of the validation of the total object. Or you might require that your mobile interface has different validation requirements from your web site (one might use a captcha, while the other might use a touch based human validation for instance).
Either way, it's important to keep in mind that validation is important both at the client, server, and various layers...
Ok, let’s clarify a few things...
The notion of ViewModel (or the actual wording of ViewModel) is something introduced by Microsoft Martin Fowler. In fact, a ViewModel is nothing more than a simple class.
In reality, your Views are strongly typed to classes. Period. To avoid confusion, the wording ViewModel came up to help people understand that
“this class, will be used by your View”
hence why we call them ViewModel.
In addition, although many books, articles and examples use the word ViewModel, let's not forget that it's nothing more than just a Model.
In fact, did you ever noticed why there is a Models folder inside an MVC application and not a ViewModels folder?
Also, ever noticed how at the top of a View you have #model directive and not # viewmodel directive?
That's because everything could be a model.
By the way, for clarity, you are more than welcomed to delete (or rename) the Models folder and create a new one called ViewModels if that helps.
Regardless of what you do, you’ll ultimately call #model and not #viewmodel at the top of your pages.
Another similar example would be DTO classes. DTO classes are nothing more than regular classes but they are suffixed with DTO to help people (programmers) differentiate between all the other classes (including View Models).
In a recent project I’ve worked on, that notion wasn’t fully grasped by the team so instead of having their Views strongly typed to Models, they would have their Views strongly typed to DTO classes. In theory and in practice everything was working but they soon found out that they had properties such as IsVisible inside their DTO’s when in fact; these kind of properties should belongs to your ViewModel classes since they are used for UI logic.
So far, I haven’t answered your question but I do have a similar post regarding a quick architecture. You can read the post here
Another thing I’d like to point out is that if and only if your Service Layer plans on servicing other things such as a Winform application, Mobile web site, etc...then your Service Layer should not be receiving ViewModels.
Your Service Layer should not have the notion of what is a ViewModel. It should only accept, receive, send, etc... POCO classes.
This means that from your Controller, inside your ActionResult, once the ModelState is Valid, you need to transform your ViewModel into a POCO which in turn, will be sent to the method inside your Service Layer.
In other words, I’d use/install the Automapper nugget package and create some extension methods that would convert a ViewModel into a POCO and vice-versa (POCO into a ViewModel).
This way, your AddNewPerson() method would receive a Person object for its parameter instead of receiving a PersonViewModel parameter.
Remember, this is only valid if and only if your Service Layer plans on servicing other things...
If that's not the case, then feel free to have your Service Layer receive, send, add, etc...ViewModels instead of POCOs. This is up to you and your team.
Remember, there are many ways to skin a cat.
Hope this helps.

Advice on isolating my nhibernate layer such that I could swap it out with EF potentially

Ok it seems my project setup could use some improvments.
I currently have:
1. ASP.NET MVC3 Web project
2. NHibernate project with Repositories/Mappings and some session code.
3. Entities (models used in nhibernate like User.cs)
4. Interfaces (like IUser, IRepository<IUser>, IUserRepository...)
5. Common (UserService, ..)
Now the issue is that I my nhibernate models now need to implement IUser, which I don't like, but I was forced to do this since my IRepository is generic, and I could use IRepository<User> since User is in another project, so I had to create an interface and do IRepository<IUser>
I will never need to have another implemention of User, so this is bugging me.
How can I fix this while keeping things seperate so I can swap out my ORM?
The IUser interface must be defined in the Entities layer if your entities implement it, not in the Interfaces layer. Also I would probably rename this generic Interfaces layer to Repositories or AbstractRepositories or something. Also I would rename the Common layer to Services if it contains services aggregating your repositories.
So the picture could be:
ASP.NET MVC3 Web project
NHibernate project with Repositories/Mappings and some session code.
Domain Entities (models used in nhibernate like User.cs and implementing domain interfaces like IUser)
Repositories (like IRepository<IUser>, IUserRepository...)
Services (UserService, ..)
I think you should approach this problem from Domain Driven Design perspective. Domain should be persistent-ignorant. Proper implementation of DDD repository is a key here. Repository interface is specific, business-focused, not generic. Repository implementation encapsulates all the data access technicalities (ORM). Please take a look a this answer and these 2 articles:
How to write a repository
DDD: The Generic Repository
Your entities should be concrete types, not interfaces. Although you may never need to swap your ORM (as Ladislav is saying in comments), you should design it as if you will need to swap it. This mindset will really help you achieve persistence ignorance.

Keeping dependency inject component out of main code base

I have a MVC app that uses ninject to inject service dependencies into controllers and it works well. However I also have some domain objects that require these services in their constructors and I want to resolve these dependencies using ninject, but don't want to reference ninject directly in my domain objects assembly. I have read lots of questions and answers here but its still not clear to me the best way to go about this. For example I have a ShoppingCart domain object that needs an instance of a IProductCatalogService passed to its constructor. What is the best pattern to create an instance of a shopping cart? I could have a reference to the root kernel and call out to that, but that would mean having references to ninject throughout my domain assembly. Should I wrap access to the kernel in a factory class?
Any thoughts or suggestions welcome!
It is usually considered bad practice to have services in domain objects. I think you need to rethink exactly what you are attempting to achieve. Why does a ShoppingCart need to consume Product Catalog Services?
From a Domain perspective I would assume that a ShoppingCart would consist of many 'items', have properties like total etc and potentially would be passed to an ordering service. Your controller actions would update the Shopping Cart domain by adding items, removing items, etc, etc.
If you really need to consider this option, is to use commonservicelocator. This will separate out your (direct) dependency on ninject.

Dependency Injection: How to inject when using a multi-project solution

hope this question is not all too stupid, I'm trying to get a hold of more advanced programming principles and was thus trying to get used to Dependency Injection using Ninject.
So, my model is split up into several different .dll-projects. One project defines the model specifications (Interfaces) and a couple of others implement these interfaces. All model projects need to use some sort of database system, so they all need access to yet another .dll which implements all my database logic. It is important that all of them can access the same instance of my database object, though, so if wouldn't suffice to just create one instance for each model.
I'm not quite sure how to achieve this using dependency injection, though. My first thought was to create a seperate DI-project and bind all interfaces to their respective implementation, so the DI-project needed references to all the other projects (model interfaces & implementations, database system etc.). Then again, the models would need access to the DI project since, for example, they'd need to request the database system from the DI System (Ninject). Of course this would create a circular reference (binding DI project to model and model to DI project), so it's not possible.
Long story short, I'd need a programming pattern that allows me to bind model interfaces to their implementations but that also allows the model implementations to request other dependencies from Ninject, e.g.
IModel1 -> Model1
IModel2 -> Model2 (different project)
IDatabase -> Database (different project)
Model1 -> request IDatabase -> get Database instance
Model2 -> request IDatabase -> get the same Database instance
Would be glad to get a couple of suggestions, at the moment I'm stuck and out of ideas ;)
Thanks!
the models would need access to the DI project since, for example,
they'd need to request the database system from the DI System
(Ninject)
When you use dependency injection, the model shouldn't need to access the DI framework, since it is the DI framework that injects dependencies. The model objects should not be asking the DI container. When the your objects are asking the container for dependencies it is not called Dependency Injection, but Service Locator. Service Locator is an anti-pattern.
My first thought was to create a seperate DI-project
When you have a single application (e.g. a web app), the usual thing to do is completely configure the DI container in the startup project, as close as possible to the application’s entry point. This entry point where all object graphs are composed is called the Composition Root.
All model projects need to use some sort of database system, so they
all need access to yet another .dll which implements all my database
logic
Try making POCO (plain old CLR objects) model/entity objects, or at least, ensure that those objects don't need to reference any other project, which makes your architecture (and testing) much easier.
Use Ninject with the Register Resolve Release pattern from within a Composition Root.
The client application would use Ninject to inject the actual database and model implementations.
The client application therefore needs to reference the database, idatabase, model and imodel projects.
The idatabase and database projects need to reference the model project, as the methods will return model objects or collections of model objects. Have a look at the repository pattern.
Your model doesn't need to reference any of your projects.

ASP.NET MVC: What goes where?

I am about to start developing a medium sized ASP.Net MVC application.
I am trying to get the design right. I intend to have the following layers:
UI layer (MVC)
Service Layer
Repository Layer
Data Access Layer
I will be using Unity as my IOC container and EF4.1 Code First for Data Access.
The app will be split into several assemblies. I have a problem deciding which assemblies I will need
and where to put the following:
Entities/Domain objects e.g. Customer, Invoice
DTOs e.g. CustomerDTO, InvoiceDTO
Service interfaces e.g. ICustomerService
Repository Interfaces e.g. ICustomerRepository
Services(Service interface implementation classes) e.g. CustomerService
Repositories (Repository Service implementation classes) e.g. CustomerRepository
ViewModels e.g. CustomerViewModel
Enums
My question is:
How do you usually split yours and why?
Edit: prompted by the #TheHurt's answer.
How would the references be between the assemblies, i.e. which assembly would be referencing which?
This is how I might tackle it:
App.UI assembly:
ViewModels go in Models area.
App.Repository assembly:
Abstract implementation of concrete repository.
ICustomerRepository
App.Repository.SQL:
Concrete implementation.
EFCF POCOs
App.Services assembly:
Abstract service.
ICustomerService
DTOs
App.Services.Implementation:
Concrete service.
CustomerService
App.Common:
Shared code.
Enums
There are a couple issues that I still struggle with. You lose the data annotations from EFCF when you cross the services boundary. So then you have to do server side validation or you have to keep your view models validation in sync with the repository entities. It feels that the more layered things are, the more DRY is violated. I suppose that is par for the course though when your view models don't map to your entities directly. You could have your view models be your DTOs and toss them into the Common assembly, but that seems to couple things too tightly if you have the need to be super flexible with your services.
EDIT
If you are wanting to integrate WCF into the mix you would probably want to create data contracts that are very close to the MVC view model (or use the contracts as the view model). You probably wouldn't expose that to the world as the service would be specific to that implementation of your MVC site, spin up another service for public consumption. If you are doing a WCF service you probably want to have all of your business logic in the service, the controllers would just handle navigation logic.
Side note, I try to stay away from the "metal" as much as possible, while developing a design that will allow me to separate the code into various layers in the future. If I cannot clearly explain the various system layers to my manager with one sheet of paper, the design is more than likely too complex. Everything for the most part will look pretty in Visio if it is designed well.
As far as how things reference each other: UI would ref the Serivce (or service implementation, which may not be needed. Just keep it all in the same place.). Service refs the Repository. The repository implementation refs nothing, since it is loaded by IOC. Everything refs Common.

Resources