I have an asp.net mvc 2.0 application that contains Areas/Modules like calendar, admin, etc... There may be cases where more than one area needs to access the same Repo, so I am not sure where to put the Data Access Layers and Repositories.
First Option:
Should I create Data Access Layer files (Linq to SQL in my case) with their accompanying Repositories for each area, so each area only contains the Tables, and Repositories needed by those areas.
The benefit is that everything needed to run that module is one place, so it is more encapsulated (in my mind anyway). The downside is that I may have duplicate queries, because other modules may use the same query.
Second Option
Or, would it be better to place the DAL and Repositories outside the Area's and treat them as Global?
The advantage is I won't have any duplicate queries, but I may be loading a lot of unnecessary queries and DAL tables up for certain modules. It is also more work to reuse or modify these modules for future projects (though the chance of reusing them is slim to none :))
Which option makes more sense? If someone has a better way I'd love to hear it.
Thanks!
I would move them out into their own assembly/class library and create repositories based on "aggregates." Meaning, create a repository and DataContext for all operations that share a purpose (i.e. posts, comments, tags, etc).
This will help separate what each DataContext should be doing and minimize the tracking that the DataContext is doing behind the scenes.
Also, I'm not sure what you mean by, "but I may be loading a lot of unnecessary queries and DAL tables up for certain modules." If you monitor the SQL that Linq is creating you can tune your queries pretty easily. Create public methods in your repositories that only return the appropriate number of records from the appropriate tables. You'll be surprised how efficient you can get the SQL with Linq minimizing "unnecessary queries."
Related
Typically I have started new projects with a solution containing:
Web project: contains the ASP.NET MVC or Web API controllers, Javascript code etc. Makes calls to class library
Class library1: contains DbContext, EF data model, a class with CRUD methods to interface with Db via the DbContext and various "utility" methods
Class library2: contains only POCO classes. This library is referenced by both the web project and library1
Ok, that works well, but when the amount of "business logic" starts to increase, this gets kinda messy, since I start putting in more rules that the business gives you. Makes me think there needs another "layer" or library where we put "business logic" that really is above/beyond just getting a data returned as a filtered list of POCO objects. Things such as checking attributes of orders based on some rules defined by some group within the business.
My question then is: would you force every call from the client layer to go through the business library (see image below case #2), even for simple cases where you just need a simple list of lookup values of some sort?
This question is likely to attract opinionated answers. My take on is - yes I would force everything to go through the business library.
To have consistency more than anything else really, this way you can be sure:
A new member of your team is not trying to understand why some of the DB operations are happening through a different layer compared to other ones.
When you (or some other developer) are adding / removing functionality that belongs to interacting with DB, the location of it is well known.
When there's a problem regarding the DB layer / access / queries - simpler to locate the problem.
If you are testing that layer / methods - we find it to be more convenient to have everything in the same place. (Testability definitely increases) We still split the stuff across files.
We use Dependency Injection - so if you need DB access, you just inject the interface which sets up the connection for you and you're done.
Depending on how your setup is, if you're logging DB related stuff separately (monitoring the QoS of queries separately as an example) this also ensures that you don't end up adding that custom logging all over the code for those simple lookups.
Makes the dependency chain more manageable.
Now - this is not to say that it doesn't get complicated, it does. However there are further ways which you can split things, you don't necessarily need to have a gigantic DBContext class which is handling N number of different queries, depending on our design, we might end up splitting it with partial classes so different functionalities end up on different files, their tests also map to different files; we think this improves overall maintainability.
I'm building a MVC4 app, I've used EF5 model first, and kept it pretty simple. This isn't going to a huge application, there will only ever be 4 or 5 people on it at once and all users will be authenticated before being able to access any part of the application, it's very simply a place order - dispatcher sees order - dispatcher compeletes order sort of application.
Basically my question is do I need to be worrying about repositories and ViewModels if the size and scope of my application is so small. Any view that is strongly typed to a domain entity is using all of the properties within that entity. I'm using TryOrUpdateModel in my controllers and have read some things saying this can cause a lot of problems, but not a lot of information on exactly what those problems can be. I don't want to use an incredibly complicated pattern for a very simple app.
Hopefully I've given enough detail, if anyone wants to see my code just ask, I'm really at a roadblock here though, and could really use some advice from the community. Thanks so much!
ViewModels: Yes
I only see bad points when passing an EF Entities directly to a view:
You need to do manual whitelisting or blacklisting to prevent over-posting and mass assignment
It becomes very easy to accidentally lazy load extra data from your view, resulting in select N+1 problems
In my personal opinion, a model should closely resembly the information displayed on the view and in most cases (except for basic CRUD stuff), a view contains information from more than one Entity
Repositories: No
The Entity Framework DbContext already is an implementation of the Repository and Unit of Work patterns. If you want everything to be testable, just test against a separate database. If you want to make things loosely coupled, there are ways to do that with EF without using repositories too. To be honest, I really don't understand the popularity of custom repositories.
In my experience, the requirements on a software solution tend to evolve over time well beyond the initial requirement set.
By following architectural best practices now, you will be much better able to accommodate changes to the solution over its entire lifetime.
The Respository pattern and ViewModels are both powerful, and not very difficult or time consuming to implement. I would suggest using them even for small projects.
Yes, you still want to use a repository and view models. Both of these tools allow you to place code in one place instead of all over the place and will save you time. More than likely, it will save you copy paste errors too.
Moreover, having these tools in place will allow you to make expansions to the system easier in the future, instead of having to pour through all of the code which will have poor readability.
Separating your concerns will lead to less code overall, a more efficient system, and smaller controllers / code sections. View models and a repository are not heavily intrusive to implement. It is not like you are going to implement a controller factory or dependency injection.
I'm building an MVC3 app, trying to use IoC and constructor injection. My database has (so far) about 50 tables. I am using EF4 (w/ POCO T4 template) for my DAC code. I am using the repository pattern, and each table has its own repository. My service classes in my service layer are injected w/ these repositories.
Problem: My service classes are growing in the number of repositories they need. In some cases, I am approaching 10 repositories, and it's starting to smell.
Is there a common approach for designing repositories and service classes such that the services don't require so many repositories?
Here are my thoughts, I'm just not sure which one is right:
1) This is a sign I should consider combining/grouping my repositories into related sections of tables, reducing the number or dependent repositories per service class. The problem with this approach, though, is that it will bloat and complicate my repositories, and will keep me from being able to use a common interface for all repositories (standard methods for data retrieval/update).
2) This is a sign I should consider breaking my services into groups based on my repositories (tables). Problem with this is that some of my service methods share common implementation, and breaking these across classes may complicate my dependencies.
3) This is a sign that I don't know what I'm doing, and have something fundamentally wrong that I'm not even able to see.
UPDATE: For an idea of how I'm implementing EF4 and repositories, check out this sample app on codeplex (I used version 1). However, looking at some of the comments there (and here), looks like I need to do a bit more reading to make sure this is the route I want to take -- sounds like it may not be.
Chandermani is right that some of your tables might not be core domain classes. This means you would never search for that data except in terms of a single type of parent entity. In those cases you can reference them as "complex types" rather than full-blown entities, and EF will still take care of you.
I am using the repository pattern, and each table has its own repository
I hope you're not writing these yourself from scratch.
The EF 4.1 already implements the Repository Pattern (DbSet), and the Unit of Work pattern (DbContext). The older versions do too, though the DbContext template can easily be tweaked to provide a clean mockable implementation by changing those properties to an IDbSet.
I've seen several tutorial articles where people still write their own, though. It is strange to me, because they usually don't provide a justification, other than the fact that they are "implementing the Repository Pattern".
Writing wrappers for these repositories for access methods like FindById make it slightly easier to access, but as you've seen is a big amount of effort potentially little payback. Personally, unless I find that there is interesting domain logic or complex queries to be encapsulated, I don't even bother and just use Linq directly against the IDbSet.
My service classes in my service layer are injected w/ these repositories.
Even if you choose to use custom query wrappers, you might choose to simply inject the DbContext, and let the service code instantiate the wrappers it needs. You'd still be able to mock your data access layer, you just wouldn't be able to mock up the wrapper code. I'd still recommend you inject less generic ones though, because complex implementation is exactly the type of thing you'd like to be able to factor out in maintenance, or replace with mocks.
If you look at DDD Aggregate Root pattern and try to see you data in this perspective you would realize that many of the table do not have a independent existence at all. Their data is only valid in context of their parent. Most of the operations on them require you to get the parent as well. If you can group such tables and find the parent entity\repository all other child repository can be removed. The complexity of associating the parent child which till now you would be doing in your business layer (assuming you are retrieving parent and child using independent repo) not would be shifted to the DAL
Refactoring the Service interface is also a viable option, and any common functionality can be moved into a base class and\or can be itself defined as a service which is consumed by all your existing services (Is A vs Has A)
#Chandermani has a good point about aggregate roots. Repositories should not, necessary have a 1:1 mapping to tables.
Getting large numbers of dependencies injected in is a good sign your services are doing too much. Follow the Single Responsibility Principle, and refactor them into more manageable pieces.
are your services writing to all of the repositories? i find that my services line up pretty closely with repositories, that they provide the business logic around the CRUD operations that the repository expose.
Well, not sure if that's exactly the right title, but basically I have been having a lot of problems using repositories in MVC applications in such a way that you can substitute one set of repositories, implementing a different data storage technology, for another.
For example, suppose I want to use Entity Framework for my application. However, I also want to have a set of test data implemented in hard-coded Lists. I would like to have a set of interfaces (IUserRepository, IProductRepository, etc. -- let's not talk about a more generic IRepository<T> for now) that both approaches can instantiate. Then, using (say) a Dependency Injection tool such as Ninject or Castle Windsor, I can switch back and forth between the entity framework provider (accessing the actual database) and the test provider (accessing the lists).
In a nutshell, here's the problem:
-- If you are going to use Entity Framework, you want your repositories returning IQueryable<SomeType>.
-- If you are going to use hard-coded lists, you do NOT want your repositories returning IQueryable, because it adds hugely to the overhead, and plus, Linq to Entities is significantly different from Linq to Objects, causing many headaches in the code that is common to both providers.
In other words, I have found that the best approach isolates all the EF-dependent code within the repositories, so that the repositories themselves return IEnumerable or IList or some such -- then both EF and some other technology can use the same repositories. Thus, all the IQueryable's would be contained WITHIN the EF repositories. That way, you can use Linq to Entities with the EF repositories, and Linq to Objects with the Test repositories.
Yet this approach puts an enormous amount of the business logic into the repositories, and results in much duplicated code -- the logic has to be duplicated in each of the repositories, even if the implementations are somewhat different.
The whole idea of the repositories as this layer that is very thin and just connects to the database is then lost -- the repositories are "repositories" of business logic as well as of data store connectivity. You can't just have Find, Save, Update, etc.
I've been unable to resolve this discrepancy between needing to isolate provider-dependent code, and having business logic in a centralized location.
Any ideas? If anyone could point me to an example of an implementation that addresses this concern, I would be most appreciative. (I've read a lot, but can't find anything that specifically talks about these issues.)
UPDATE:
I guess I'm starting to feel that it's probably not possible to have repositories that can be swapped out for different providers -- that if you are going to use Entity Framework, for example, you just have to devote your whole application to Entity Framework. Unit tests? I'm struggling with that. My practice to this point has been to set up a separate repository with hard-coded data and use that for unit testing, as well as to test the application itself before the database is set up. I think I will have to look to a different solution, perhaps some mocking tool.
But then that raises the question of why use repositories, and especially why use repository interfaces. I'm working on this. I think determining the best practice is going to take a bit of research.
What I can say? Welcome to the club ...
What you found is problem reached by many developers who followed "repository boom" with EFv4. Yes it is the problem and the problem is really complex. I discussed this several times:
ASP.NET MVC 3 and Entity Framework code first architecture
Organizationally, where should I put common queries when using Entity framework
Separate topic is why to use repositories:
Generic repository, what is the point
Basically your proposed way is a solution but do you really want it? In my opinion the result is not repository but the Data Access Object (DAO) exposing plenty of access methods. Repository definition by Martin Fowler is:
A Repository mediates between the
domain and data mapping layers, acting
like an in-memory domain object
collection. Client objects construct
query specifications declaratively and
submit them to Repository for
satisfaction. Objects can be added to
and removed from the Repository, as
they can from a simple collection of
objects, and the mapping code
encapsulated by the Repository will
carry out the appropriate operations
behind the scenes. Conceptually, a
Repository encapsulates the set of
objects persisted in a data store and
the operations performed over them,
providing a more object-oriented view
of the persistence layer. Repository
also supports the objective of
achieving a clean separation and
one-way dependency between the domain
and data mapping layers.
I believe exposing IQueryable fulfils this 100 times better then creating a public interface similar to repositories from Stored procedures era - one access method per stored procedure (fixed query).
The problem can be summarized by the rule of leaky abstraction. IQueryable is an abstraction of the database query but the features provided by IQueryable are dependent on the provider. Different provider = different feature set.
What is a conclusion? Do you want such architecture because of testing? In such case start using integration tests as proposed in first two linked answers because in my opinion it is the lest painful way. If you go with your proposed approach you should still use integration tests to verify your repositories hiding all EF related logic and queries.
So I have a layered ASP.NET MVC proof-of-concept application with good separation between presentation concerns, business logic, and infrastructure concerns. Right now it is operating off of a fake repository (i.e. LINQ queries against static IQueryable objects). I would like to create a functional SQL repository now.
That said, I don't want to simply tie it into a database that has a 1-1 mapping between tables and entities. That wouldn't meet the business need I am hoping to solve (partial integration with existing database - no hope for convention over configuration).
Do you have suggestions for which ORM / mapping tools I should consider and/or avoid?
Do you have suggestions for articles/books I could look at to help me approach this topic?
Would it be better to simply use parameterized queries in this scenario?
Entity Framework in version 4 would definitely allow you to:
have a mapping between the physical database schema and your conceptual schema, e.g. having an entity mapped to several tables, or several tables joined together forming a single business entity
grab data from views (instead of tables directly)
use stored procedures (where needed and appropriate) for INSERT, UPDATE, DELETE on every entity
NHibernate sounds like a good fit for what you are looking for. You will be able to make your repositories call queries in either HQL or using the API, either way you can get to your database and shape the data to fit the way your repository is being used. It will always be hard to make a square peg fit into a round hole though. SO has lots of nice support when you get into using NHibernate, good luck.
As you mentioned in the question, it is very debatable to choose an ORM. Different people will have different project needs. I am not exactly sure what will take priority for you. Here is what I have tried myself.
NHibernate seems to be the most commonly used ORM in DotNet projects. I feel it suffers from a typical open source problem. It offers so many features but the documentation really sucks. If you have lots of time at your disposal you can give it a shot.
Another options is to go for something like Entity Framework. Its very easy to set up and get up and running. With version 4.0 and the CTP there is provison for code first as well as fluent mapping and configuration. Since you have said you would want to keep the domain model separated EF 4 will help you because it has a notion of conceptual model which is an abstraction over the mapping layer.
You can refer to few links below for the blogs I had written based on my experience
http://nileshgule.blogspot.com/2010/08/entity-framework-hello-world.html
http://nileshgule.blogspot.com/2010/09/nhibernate-code-first-approach-with.html
http://nileshgule.blogspot.com/2010/09/entity-framework-first-query-using.html
http://nileshgule.blogspot.com/2010/09/entity-framework-learning-series.html