i would like to develop an n-tier application. where i want to introduce entity framework with Repository, specification and Unit-of-work pattern within DAL layer. and domain object should be exposed as Self Tracking entities and there is thin WCF wrapper layer on top of business components.
please give me an example.
Thanks
Kawsar
You can create a generic class that is base of your data service:
class BaseDataService<T> where T : IYourModel or EntityObject
This class implement common action like Save(), GetItem(), Delete(),Get...
Now you can for Entities of your domain create a class that inherit from this base class:
class FooDataService:BaseDataService<Foo>
Related
Firstly i must say, i know their is a very close question i found on stackoverflow, but my question is a little different.
I have n-tier application in asp .net mvc, in which I have: A BOL project(which has EF classes and db object etc), BLL project(which has buiseness logic), than we have DAL project(which has db interaction logic, and it uses EF dbcontext from BOL). And a main mvc project which ahs controllers and views etc.
Now, we are using repository pattern, we have many Repositories in BLL with their interfaces. And also we have many repositories in DAL which are without interfaces though. But all of those DAL repositories have one DbContext member in them, which is being created in their constructors, so each DAL repository is interacting with separate instance of DbContext which it has created.
And in our main mvc project, we have used ninject to inject BLL repositories in controllers constructors (in request scope). Now, the issue we are facing is, that each BLL repository has references to one or more DAL repositories, and each of those DAL repositories are using their own seperate DbCOntext. Which is wrong and bad, thats why i am looking for the way to share one DbCOntext in all DAL repositories, per request(No matter how many BLL repositories ninject injects in my controller, just make sure only one DbContext instance is being created and used per request). And dispose that context after each request.
One way i thought was to not create DBcontext in constructor of DAL repositories. But have some method call(say initiateDbContext) for that, than also add this method in BLL repositories, which do nothing but to call the smae method of their member DAL repositories. Call that method for one BLL repository in controller constructor, and than have a method to get and set db contexts in all other repositories from the first repository. But i know this is bad approach, firstly we are creating DbContext in controller, which should be in DAL only, secondly i am adding create, get and set DbCOntext methods in DAL as well as in BLL repositories, because i need to pass DbCOntext to BLL which will pass that to the DAL repositories it communicates with internally. And that's very bad.
That's why i am asking here for any good pattern to achieve "ONE DBCONTEXT PER REQUEST IN N-TIER WITH REPOSITORY PATTERN."
If you are using dependency injection, you should use it all the way, not only in the controllers.
That means, the DBContext should be injected into the Repositories, and Ninject should be configured to resolve your DBContext with per request lifetime.
Based on the answer from #atika i searched further and implemented what he suggested(using ninject/DI in whole application rather than just in one main project of mvc) and it solved the issue, i am posting this answer to add more details and some extra issues i faced and i got to spend time googling about further, so others might save some time.
Idea is to use dependency injection throughout the solution, no matter how many projects/tiers you have in it and no matter how many repositories you have got.
So, the issue comes to the point, that if we want to use ninject or any other DI for binding all dependencies from all tiers/projects, we should have reference to all of those tiers/projects in our main mvc project, so that we can bind the dependencies in NinjectWebCommons, but this will kill the whole purpose of n-tier architecture. We don't want to do that, we want our hierarchy to sustain, like in my case
MainMVCProject->BLL->DLL->DB
So, for this, i found a very helpful article Ninject with N-Tier MVC Application - Inject Object in Business Layer.(Their are also some other approaches, one is to make a project just for bindings and add use that project to bind all dependencies, but that sounds like over engineering and overkill)
Based on which i added the following class in my BLL tier/project(after installing ninject in this project and DAL project too), which has bindings for DLL classes.
using BLL.Repositories;
using BLL.RepositoryInterfaces;
using Ninject.Modules;
using Ninject.Web.Common;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DAL;
using BOL;
namespace BLL
{
public class LayerBindings : NinjectModule
{
public override void Load()
{//add all references here like these
Bind<AdDb>().ToSelf().InRequestScope();
Bind<db_Entities>().ToSelf().InRequestScope().WithConstructorArgument("ConnectionString", BOL.CommonFunctionsBOL.ConnectionString);
}
}
}
Getting some help from howto-ninject-part-1-basics article, i managed to do many things with ninject, and used many of its features.
Now, you can see i added the bindings of DLL project in this class, which were not accessible in main mvc project. Now, i just need to load these bindings in main ninject.
Now, in NinjectWebCommons.cs file, i added following lines:
//old bindings of BLL and local project.
kernel.Bind<IUserRepository>().To<UserRepository>().InRequestScope();
//now here we bind other dependencies of DAL etc using class we added in BLL
var modules = new List<INinjectModule>
{
new BLL.LayerBindings()
};
kernel.Load(modules);
(In RegisterServices method, after local bindings and BLL objects bindings.)
After doing just this, ninject started working in all the projects and i just used constructor injection or on some places, property injections and all worked fine.
PS1: I also used property injection*(i read that this is not recommended to use property injections, use them only where you cant use constructor injections.)* for private properties and they had to be enabled with kernel.Settings.InjectNonPublic = true; line in "CreateKernel" method before returning the kernal.
Now my property injection is working for private properties too, like this:
[Ninject.Inject]
private SomeDALObject db { get; set; }
PS2: I also installed ninject.web.webapi nuget package for ninject to work with webapis, and also found this line to get an object anywhere from ninject.(I don't know if this is a good way or not, but it does return a fully constructed object which i used than. If any one can clarify or correct me if using this is right or not, that will be great.)
((TypeOfObjectYouWant)System.Web.Mvc.DependencyResolver.Current.GetService(typeof(TypeOfObjectYouWant))).DoSomething();
I hope this might help some people like me looking for proper guide on this issue.
You can write one BaseRepository and implement BaseRepository in all repository classes.
public class BaseRepository
{
public StudentEntities dbStudentEntity;
public BaseRepository()
{
dbStudentEntity = new StudentEntities();
}
}
DataRepository :
public class CurrencyData : BaseRepository,ICurrencyData
{
public List<Models.Currency> GetCurrencyList()
{
var objCurrencies = dbStudentEntity.Currencies.ToList();
List<Models.Currency> currencyList = new List<Models.Currency>();
foreach (var item in objCurrencies)
{
var model = new Models.Currency { CurrencyId = item.CurrencyId, Currency1 = item.Currency1,Code = item.Code,Symbol = item.Symbol,Country = item.Country };
currencyList.Add(model);
}
return currencyList;
}
}
I am implementing a form of CQRS that uses a single data store but separate Query and Command models. For the command side of things I am implementing DDD including Repositories, IoC and Dependency Injection. For the Query side I am using the Finder pattern as described here. Basically, a finder is similar to a Repository, but with Find methods only.
So in my application for the read side, in my DAL, I use ADO.net and raw SQL to do my queries. The ADO.Net stuff is all abstracted away into a nice helper class so that my Finder classes simply pass the query to the ADO helper which returns generic data objects which the finder/mapper class turns into read models.
Currently the Finder methods, like my command repositories, are accessed through interfaces that are injected into my controllers, but I am wondering if the interfaces, DI and IoC are overkill for the query side, as everything I have read about the read side of CQRS recommends a "thin data layer".
Why not just access my Finders directly? I understand the arguments for interfaces and DI. ie Separation of Concerns and testability. In the case of SOC, my DAL has already separated out database specific logic by using a mapper class and putting the ADO.net stuff in a helper class. As far as testing is concerned, according to this question unit testing read models is not a necessity.
So in summary, for read models, can I just do this:
public class PersonController : Controller
{
public ActionResult Details(int id)
{
var person = new Person();
person = PersonFinder.GetByID(id);
// TODO: Map person to viewmodel
return this.View(viewmodel);
}
}
Instead of this:
public class PersonController : Controller
{
private IPersonFinder _person;
public PersonController(IPersonFinder person)
{
_person = person;
}
public ActionResult Details(int id)
{
Person person = _person.GetByID(id);
// TODO: Map person to viewmodel
return this.View(viewmodel);
}
}
Are you using both IoC and DI? That's bad ass! Anyways, the second version is the better one because it doesn't depend on a static class. Using statics will open Pandora's box, don't do it, for all the reasons that using static is bad.
You really don't get any benefits for using a static class and once you are already using a DI Container, there's no additional cost. And you are using the Finders directly but you let the DI Container instantiate one instead of you calling a static object.
Update
A thin read layer refers to using a simplified read model instead of the rich domain objects. It is unrelated to DI, it doesn't matter how the query service is built or by whom, it matters to not involve the business objects in queries.
Read/Write separation is completely unrelated to coding techniques like dependency injection. Your read models are serving fewer purposes than your combined read/write models were before. Could you consider ditching all the server-side code and just using your database's native REST API? Could you wire your controller to directly query the database with SQL and return the data as JSON? Do you need a generic repository-like pattern to deal with specific read requests?
I am exploring the idea of implementing a web service api using WCF Data Services and EF4. Realizing that some operations require complex business logic, I decided to create a partial class the same name as the main EF data context partial class and implement additional methods there to handle the more complex business logic. When the EF context object is used directly, the additional method shows up (via intellisense) and works properly. When the EF classes are exposed through a WCF Data Service and a Service Reference is created and consumed in another project, the new method does not show up in intellisense or in the generated Service.cs file (of course, I updated the reference and even deleted it and re-added it). The native data methods (i.e. context.AddObject() and context.AddToPeople()) work properly, but the new method isn't even available.
My EF classes look something like this:
namespace PeopleModel
{
//EF generated class
public partial class PeopleEntities : ObjectContext
{
//Constructors here
//Partial Methods here
//etc....
}
//Entity classes here
//My added partial class
public partial class PeopleEntities
{
public void AddPerson(Person person)
{
base.AddObject("People", person);
}
}
}
There's nothing special about the .svc file. The Reference.cs file containing the auto generated proxy classes do not have the new "AddPerson()" method.
My questions are:
1. Any idea why the web service doesn't see the added partial class, but when directly using the EF objects the method is there and works properly?
2. Is using a partial class with additional methods a good solution to the problem of handling complex business rules with an EF generated model?
I like the idea of letting the oData framework provide a querying mechanism on the exposed data objects and the fact that you can have a restful web service with some of the benefits of SOAP.
Service operations are only recognized if they are present on the class which derives from DataService. The WCF Data Service will not look into the context class for these. Also note that methods are not exposed by default, you need to attribute them with either WebGet or WebInvoke and allow access to them in your InitializeService implementation.
http://msdn.microsoft.com/en-us/library/cc668788.aspx
I am still having a hard time wrapping my head around this. I want to separate my layers (dlls) like so:
1) MyProject.Web.dll - MVC Web App (Controllers, Models (Edit/View), Views)
2) MyProject.Services.dll - Service Layer (Business Logic)
3) MyProject.Repositories.dll - Repositories
4) MyProject.Domain.dll - POCO Classes
5) MyProject.Data.dll - EF4
Workflow:
1) Controllers call Services to get objects to populate View/Edit Models.
2) Services call Repositories to get/persist objects.
3) Repositories call EF to get/persist objects to and from SQL Server.
My Repositories return IQueryable(Of T) and inside them they utilize ObjectSet(Of T).
So as I see this, the layers depend on exactly the next layer down and the lib that contains the POCO classes?
A few concerns:
1) Now for my Repositories to work correctly with EF, they will depend on System.Data.Objects, now I have a tight coupling with EF in my repository layer, is that bad?
2) I am using the UnitOfWork pattern. Where should that live? It has a Property Context As ObjectContext, so that is tightly coupled to EF as well. Bad?
3) How can i use DI to make this easier?
I want this to be a loosely coupled as possible for testing. Any suggestions?
---------- Edit ----------
Please let me know if I am on the right track here. Also, so the Service gets injected with an IRepository(Of Category) right, how does it know the difference between that and the concrete class of EFRepository(Of T)? Same with the UnitOfWork and the Service?
Once someone helps me figure this out to where I understand it, I know it will have seemed trivial, but man I am having a heck of a time wrapping my head around this!!
Controller
Public Class CategoryController
Private _Service As Domain.Interfaces.IService
Public Sub New(ByVal Service As Domain.Interfaces.IService)
_Service = Service
End Sub
Function ListCategories() As ActionResult
Dim Model As New CategoryViewModel
Using UOW As New Repositories.EFUnitOfWork
Mapper.Map(Of Category, CategoryViewModel)(_Service.GetCategories)
End Using
Return View(Model)
End Function
End Class
Service
Public Class CategoryService
Private Repository As Domain.Interfaces.IRepository(Of Domain.Category)
Private UnitOfWork As Domain.Interfaces.IUnitOfWork
Public Sub New(ByVal UnitOfWork As Domain.Interfaces.IUnitOfWork, ByVal Repository As Domain.Interfaces.IRepository(Of Domain.Category))
UnitOfWork = UnitOfWork
Repository = Repository
End Sub
Public Function GetCategories() As IEnumerable(Of Domain.Category)
Return Repository.GetAll()
End Function
End Class
Repository and UnitOfWork
Public MustInherit Class RepositoryBase(Of T As Class)
Implements Domain.Interfaces.IRepository(Of T)
End Class
Public Class EFRepository(Of T As Class)
Inherits RepositoryBase(Of T)
End Class
Public Class EFUnitOfWork
Implements Domain.Interfaces.IUnitOfWork
Public Property Context As ObjectContext
Public Sub Commit() Implements Domain.Interfaces.IUnitOfWork.Commit
End Sub
End Class
Original Answer
No. However, to avoid coupling the Services to this, have an ISomethingRepository interface in your domain layer. This will be resolved by your IoC container.
The Unit of Work patterns should be implemented with your Repositories. Use the same solution to decoupling this as I suggested with decoupling your repositories from your services. Create an IUnitOfWork or IUnitOfWork<TContext> in your domain layer, and put the implementation in your Repository layer. I don't see any reason that your repository implementation needs to be separate from your Data layer, if all the Repositories do is persist data to the ObjectContext in data layer. The Repository interface is domain logic, but the implementation is a data concern
You can use DI to inject your services into the controllers and your repositories into your services. With DI, your service will have a dependency on the repository interface ISomethingRepository, and will receive the implementation of the EFSomethingRepository without being coupled to the data/repository assembly. Basically, your IControllerFactory implementation will get the IoC container to provide all the constructor dependencies for the Controller. This will require that the IoC container also provides all the controllers' constructor dependencies (service) their constructor dependencies (repositories) as well. All of your assemblies will have a dependency on your domain layer, (which has the repository and service interfaces), but will not have dependencies on each other, because they are dependent on the interface and not the implementation. You will either need a separate assembly for the Dependency Resolution or you will need to include that code in your Web project. ( I would recommend a separate assembly). The only assembly with a dependency on the Dependency Resolution assembly will be the UI assembly, although even this is not completely necessary if you use an IHttpModule implementation to register your dependencies at the Application_Start event (the project will still need a copy of the dll in your bin folder, but a project reference is not necessary). There are plenty of suitable open source IoC containers. The best one depends a lot on what you choose. I personally like StructureMap. Both it, and Ninject are reliable and well documented DI frameworks.
Response to Sam Striano's Edits
It's been years since I've coded in VB so my syntax may be off.
Public Class CategoryController
Private _Service As Domain.Interfaces.IService
'This is good.
Public Sub New(ByVal Service As Domain.Interfaces.IService)
_Service = Service
End Sub
Function ListCategories() As ActionResult
Dim Model As New CategoryViewModel
Using UOW As New Repositories.EFUnitOfWork
This doesn't need to be in the controller. Move it into the Repository and have it surround the actual transaction. Also, you don't want your controller to have a dependency on the data layer.
Mapper.Map(Of Category, CategoryViewModel)(_Service.GetCategories)
Is this a call to AutoMapper? Not related to your original question, but, you should relocate the mapping functionality to an ActionFilter so your return is just Return View(_Service.GetCategories)
End Using
Return View(Model)
End Function
The Service class had no problems.
The Repository and Unit of Work look mostly incomplete. Your Repository should new up the ObjectContext and inject it into the Unit of Work, then execute all transactions in the scope of the Unit of Work (similar to what you did in the controller). The problem with having it in the Controller is it's possible that a single Service call could be scoped to multiple units of work. Here is a good article on how to implement Unit of Work. http://martinfowler.com/eaaCatalog/unitOfWork.html. Martin Fowler's books and website are great sources of information on these types of topics.
To answer your concerns in order
1) Not necessarily bad, kind of depends on how likely you are to stick with EF. There are several things you could do to reduce this. One relatively low cost (assuming you have some Inversion of Control setup, if not skip to 3) is to only reference interfaces of your repositories from your services.
2) Same again, I think you could spend a lot of time not making your application not coupled to EF but you have to ask yourself if this change of direction would not make for other changes as well. Again, a layer of indirection could be brought in through interfacing and easily swap out one repository implementation with another later.
3) Inversion of Control should again allow all the testing you'd want. Thus no need for many direct references at all and to test any layer in isolation.
UPDATE for requested sample.
public class QuestionService : IQuestionService
{
private readonly IQuestionRepository _questionRepository;
public QuestionService(IQuestionRepository questionRepository){
_questionRepository = questionRepository
}
}
Thus your service only knows of an interface which can be mocked or faked within your unit tests. It is all pretty standard IoC stuff. There is lots of good reference out there on this, if a lot of this is new to you then I'd recommend some a book to give you the full story.
I would suggest using MEF. It gives you the dependency injection framework you want but it isn't full-fledged; it's excellent for unit test. Here are a few answers to a related question: Simplifying Testing through design considerations while utilizing dependency injection
Full code exmple can be found here with MEF and Repository Pattern (also uses EFCodeFirst).
I'm trying to be a better developer...
What I'm working with:
.Net MVC Framework 1.0
Entity Framework 3.5
I've been doing some reading and I think what i want to do is:
Create a repository for each aggregate in the domain. An Order repository for example will manage an Order's OrderItems.
Create a service layer to handle business logic. Each repository will have a corresponding service object with similar methods.
Create DTOs to past between the repository and service
Possibly create ViewModels which are classes for the View to consume.
I have a base repository interface which my aggregate repository interfaces will implement...
public interface IRepository<T>
{
IEnumerable<T> ListAll();
T GetById(int id);
bool Add(T entity);
bool Remove(T entity);
}
My Order Repository interface is defined as follows...there will likely be additional methods as I get more into this learning exercise.
public interface IOrderRepository : IRepository<Order>
{
}
My service classes are essentially defined the same as the repositories except that each service implementation includes the business logic. The services will take a repository interface in the constructor (I'm not ready for IoC in this exercise but believe that is where I'd like to end up down the road).
The repository implementations will push and pull from the database using Entity Framework. When retrieving data; the methods will only return the DTOs and not the EF generated objects
The services (as I'm calling them) will control the repository and perform the business logic. The services are what you will see in the controller i.e. _orderService.GetById(1).
This is where I started flip flopping and could use some feedback...should I maybe have my service classes populate ViewModel classes...should I not have ViewModel classes....maybe that is too much mapping from one type to another?
I would love to get some feedback on the direction I am heading with regards to a separation of concerns.
Thanks
I think you are heading in the right direction about the Repository pattern. Regarding your question about the ViewModel classes, i suggest that you use something that transforms the output of the business service method outputs to some desired outputs. For example your Order business service may have a method called GetOrders(). Using a custom attribute you may define the view class type for it. The view is able to get the output of this method, possibly joins it with other kinds of data and returns the result as a collection of objects with anonymous types. In this case the view will take IQueryable<Order> or IEnumerable<Order> as input and returns IList as the output.
This method will help you greatly when you need to show different kinds of views of your data on the client side. We have already utilized something similar (but more complex) to this method in our company's framework.