Here's my problem: I use EntityFramework 4.1 Model first, and I have two assembly (Domain and Store)
The domain contains all my business logic
Store manages all persistence logic to the database
So I do not want any entity framework query in my Domain. I use a repository to expose the Store. The Hic! My edmx is in the Store, so the TT that generates my business classes too. As I want my business classes in the assembly's Domain , I moved the TT into the Domain and change the namespace of code generator. I must refer my Store to know my Domain classes (logic !). But how to call my repository from my Domain without creating a circular reference ...?
Summary:
My Store reference Domain to know the business classes.
My Domain reference Store to know the repository
You need a repository interface in your domain layer. Then the repository implementation is in your infrastructure layer, and uses EF. This way your infrastructure layer depends on your domain layer (via the implementation of the repository interface, and the creation/retrieval of domain entities), but the domain does not depend on the infrastructure layer.
A good explanation of this general architectural pattern is given in Jeffrey Palermo's articles on the "onion architecture".
Related
I could do with some guidance about how to setup the MVC Repositories with the following scenario.
Below is a sample of the main tables in my project.
Entity
central table used to store common data
can be an Article, Person, Job or Post
an Entity can have 1 or more Tags
Tag
used to store Tag values
Article
stores Article specific information
Person
stores Person specific information
Job
stores Job specific information
Post
stores Post specific information
With the above information in mind, should I be looking to create a Repository
Entity Repository
handles CRUD for an Entity
handles CRUD for Tags
Article
inherits Entity Repository
handles CRUD for a Article
Person
inherits Entity Repository
handles CRUD for a Person
Job
inherits Entity Repository
handles CRUD for a Job
Post
inherits Entity Repository
handles CRUD for a Post
I'm using PetaPoco as my ORM. Is this a suitable approach?
Well, yes and no. Yes, typically, a repository is for one "thing", so each entity would need it's own repository. However, if you're using Entity Framework or another ORM, then implementing the repository pattern on top of it is a hugely bad idea. The entire purpose of an ORM is to give you repositories. In the case of Entity Framework, each DbSet is a repository and your DbContext is your Unit of Work. Adding another layer on top of this will see you merely proxying one method call to another method call on your context, providing no benefit, and increasing the complexity and maintenance costs of your application.
Either just use your ORM directly, or if you want to abstract it, use a service pattern and create endpoints that satisfy specific queries you will need in your application. Depending on the size of your application, you might only need one service, rather than one per type.
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.
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.
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.
I have an ASP.NET MVC 2 application with a POCO domain model and an NHibernate repository layer. My domain model has no awareness of my viewmodels so I use automapper to go from viewmodel to entity and vice/versa.
When I introduced WCF to my project (a late requirement), I started having to deal with disconnected objects. That is, I retrieve an entity from the database with NHibernate and once that entity is serialized it becomes disconnected and each child collection is loaded regardless of whether or not I plan on using it meaning I'm doing alot of unnecessary database work.
After reading up on this, I see that it is highly recommended that you not expose your entities outside of your domain project and you should instead use DTOs.
I see the reason for this but I'm having trouble figuring out how to implement it.
Do I map from viewmodel to DTO in ASP.NET MVC, send DTOs through the service layer, and map from DTO to entity in the service layer? Where should I define my DTOs?
I like to have my service layer keep entities encapsulated within it, and return/receive only DTOs. I keep the service contracts as well as the DTO's in a separate assembly which both the MVC project and the Service implementation reference.
Inside the service call implementation, the service maps dto's to entities, then does the interaction with repositories and other entities as it needs to.
On the app/mvc project I sometimes will get lazy and just use DTO's as the models for certain actions (especially CRUDy ones). If i need a projection or something like that, then I'll make a viewmodel and convert between DTO and viewmodel with automapper etc.
How exposed your entities are is a subject of much debate. Some people will push them all the way to the view/app layer. I prefer to keep them in the service layer. I find that when the entities leave the service layer, you find yourself doing business logic type stuff anywhere where they're interacted with, stuff that should probably reside in a service.
I treat my DTOs like ViewModels because the UI layer ( MVC app ) is requesting them. You could go Entity -> DTO -> ViewModel but I think thats over engineering if the only consumer of your service is an MVC application. If somehow the DTOs will actually be used for data and not simply screen specifications then you should probably use additional mapping.
I've also simply returned entities from my WCF layer and let the automatically generated proxy objects on the client be the DTO. The entities almost become DTOs because of the proxy classes and no business logic comes over to the client.
And of course, this is all "It Depends" what your architectural goals are. This question is borderline subjective and argumentative IMHO.
I like defining the DTO in the MVC project and then creating extension methods to transform from domain entity to DTO (and vice-versa).
The transformation would take place in the mvc functions.
I just wrote a post about a way of getting around all this DTO <-> DO transformation. Maybe you check it out http://codeblock.engio.net/?p=17