Entity Framework Context - I'm Stuck!
Ok, so i have asked a few questions on this before, but I really am just having a hrad time understanding this.
I am using the Service/Repository/EF 4 w/Pocos approach, and I have Ninject setup and injecting the controllers with the services but I am trying to figure out where to inject the context?
I want to be able to use multiple services on the controllers which in turn might access multiple repositories using the same context so all the changes would be persisted at once.
I studied the UnitOfWork pattern, but I don't understand how the MVC (contr开发者_JAVA技巧ollers) would implement this as they only know of the service layer and the domain entities.
Edit
As Mohamed suggested below, inject the context into the repositories and then use a per request instance of it. How do you configure the binding in the MVC app? I would assume something like this:
Bind(Of IContext).To(MyDataContext)
Problem is, the MVC app knows nothing of the context, right?
Edit 2
Public Class ProductController
Private _Service As IProductService
Public Sub New(Service As IProductService)
_Service = Service
End Sub
End Class
Public Class NinjectWebModule
Public Sub New()
Bind(Of IProductService).To(ProductService)
End Sub
End Class
Public Interface IProductService
End Interface
Public Class ProductService
Implements IProductService
Private _Repository As IRepository(Of Product)
Public Sub New(Repository As IRepository(Of Product))
_Repository = Repository
End Sub
End Class
Public Class NinjectServiceModule
Public Sub New()
Bind(Of IRepository(Of Product)).To(EFRepository(Of Product))
End Sub
End Class
Public Interface IRepository(Of T As Class)
End Interface
Public Class EFRepository(Of T As Class)
Implements IRepository(Of T)
Private _UnitOfWork As MyUnitOfWork
Public Sub New (UnitOfWork As IUnitOfWork)
_UnitOfWork = UnitOfWork
End Sub
End Class
Public Class NinjectRepositoryModule
Public Sub New()
Bind(Of IUnitOfWork).To(EFUnitOfWork).InRequestScope()
End Sub
End Class
Public Interface IUnitOfWork
Sub Commit()
End Interface
Public Class EFUnitOfWork()
Implements IUnitOfWork
Public Property Context As MyContextType
Public Sub New()
_Context = New MyContextType
End Sub
End Class
I would then register all three modules from the MVC app?
Components you need:
- Repository(s) (generic or specific)
- Unit Of Work
- Services
- Controllers
What each is:
- Repository: executes queries against supplied context
- Unit of Work: wraps Entity Framework ObjectContext
- Services: calls methods on Repository
- Controllers: calls methods on Services, and calls "Commit" on Unit of Work.
With that in line, you Controller's ctor should look like this:
public ProductController(IUnitOfWork unitOfWork, IProductService productService)
You need the UoW because you mentioned you want to make changes across multiple repositories (a fairly common scenario). So by passing the UoW (which is the ObjectContext under the hood) to the Repositories, you can enable that.
Use a DI container to setup the Unit of Work as Http Context scoped.
How about injecting ObjectContext in repository classes? and use single instance per request?
Update
See this example ASP.NET MVC 3 Application using Ninject, Entity Framework 4 Code-First CTP 5, Patterns
Update 2
This example is for NHibernate session, but it is exactly the same idea with EF ObjectContext or LinqToSQL DataConext or similar stuff. Really good example. Check it and tell me what you think.
http://www.itslet.nl/?p=904
Update 3
The place where you define your DI bindings HAS to know about all the concrete implementations of course. If you really want your MVC code to not know about the context, you either
- put that code in new project that does know about it,
- or use XML for doing the bindings (there is documentation in Ninject site itself on how to do that, but it's not the default intended use of this particular DI container),
- or use Ninject Modeules (basically this means splitting your bindings, so, you can have one module that does the context bidning in the same project as the context, and the MVC just uses all discoverable Ninject Modules for binding).
This is one example of using Ninject Modules: What is the intention of Ninject modules?
精彩评论