2011-03-07 12 views
5

Ok, ya he hecho algunas preguntas sobre esto antes, pero realmente estoy teniendo mucho tiempo para entender esto.Entity Framework Context - ¡Estoy atascado!

Estoy usando el enfoque Service/Repository/EF 4 w/Pocos, y tengo Ninject configurado e inyectando los controladores con los servicios pero estoy tratando de averiguar dónde inyectar el contexto?

Quiero ser capaz de utilizar múltiples servicios en los controladores que a su vez pueden acceder a múltiples repositorios usando el mismo contexto para que todos los cambios se mantengan a la vez.

Estudié el patrón UnitOfWork, pero no entiendo cómo los MVC (controladores) implementarían esto ya que solo conocen la capa de servicio y las entidades de dominio.

Editar

Como Mohamed sugiere a continuación, inyectar el contexto en los depósitos y luego usar una por cada instancia de solicitud de la misma. ¿Cómo se configura el enlace en la aplicación MVC? Asumiría algo como esto:

Bind(Of IContext).To(MyDataContext) 

El problema es que la aplicación MVC no sabe nada del contexto, ¿verdad?

Editar 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 

Me continuación, registrar los tres módulos de la aplicación MVC?

Respuesta

7

componentes que necesita:

  1. repositorio (s) (genérica o específica)
  2. unidad de trabajo
  3. Servicios
  4. Controladores

Lo que cada uno es:

  1. Repositorio: ejecuta consultas en el contexto suministrado
  2. unidad de trabajo: envuelve Entity Framework ObjectContext
  3. Servicios: llamadas a métodos en Repositorio
  4. Controladores: llama a los métodos de Servicios, y llama "Commit" a la Unidad de trabajo.

Con esto en línea, ctor del controlador debe tener este aspecto:

public ProductController(IUnitOfWork unitOfWork, IProductService productService) 

Se necesita el UoW porque usted ha mencionado que desea realizar cambios a través de múltiples repositorios (un escenario bastante común). Entonces pasando el UoW (que es el ObjectContext bajo el capó) a los Repositorios, puedes habilitar eso.

Use un contenedor DI para configurar la Unidad de trabajo como Http Context scope-based.

+0

@ RPM1984 - Ok, entonces crearé un módulo Ninject en el proyecto de repositorios que resuelve el contexto, uno en la capa de servicios que resuelve los repositorios y otro en la aplicación mvc que resuelve los servicios y luego los registra todos desde el mvc aplicación? Entonces, en el proyecto de repositorios, tendría un EFUnitOfWork que implementa IUnitOfWork, y que tendría una propiedad de contexto del tipo MyProjectCotext, y luego el módulo Ninject vincularía (Of IUnitOfWork) .To (Of EFUnitOfWork) y tendría un alcance por solicitud. – Sam

+0

@Sam Striano - ¡listo! Muy bien resumido.:) Lo mejor que puedes hacer es comenzar, mira cómo te va, vuelve y cuéntanos qué problemas has enfrentado/cómo te ha ido e iremos desde allí. Sin embargo, no estoy seguro de lo que quiere decir con "módulo". Solo debe tener un registro: en el nivel web. Todos los componentes (repositorio/servicio/controladores) deben funcionar fuera de las interfaces y, por lo tanto, "no les importa" la implementación real. – RPM1984

+0

@RPM - El enlace Ninject tiene que saber de la implementación concreta ¿no? Entonces, ¿cómo le contarías sobre EFUnitOfWork y mantendrás el SoC? Vea mi edición anterior si quiere. – Sam

2

¿Qué le parece inyectar ObjectContext en las clases de repositorio? y usar una sola instancia por solicitud?

actualización

Ver este ejemplo ASP.NET MVC 3 Application using Ninject, Entity Framework 4 Code-First CTP 5, Patterns

Actualización 2

Este ejemplo es para la sesión de NHibernate, pero es exactamente la misma idea con EF ObjectContext o LinqToSql DataConext o cosas similares . Un buen ejemplo. Compruébalo y dime lo que piensas.

http://www.itslet.nl/?p=904

Actualización 3

El lugar donde se definen las fijaciones DI tiene que saber acerca de todas las implementaciones concretas de golf. Si realmente quiere que su código MVC no saber sobre el contexto, o bien

  • poner ese código en el nuevo proyecto que saber sobre él,
  • o utilizar XML para hacer los enlaces (existe documentación en Ninject sitio en sí mismo sobre cómo hacerlo, pero no es el uso previsto predeterminado de este contenedor DI particular),
  • o use las Módems Ninject (básicamente esto significa dividir sus enlaces, por lo tanto, puede tener un módulo que haga las pujas de contexto en el mismo proyecto que el contexto, y el MVC solo usa todos los módulos Ninject detectables para el enlace).

Este es un ejemplo de la utilización de módulos ninject: What is the intention of Ninject modules?

+0

@Mohamed - Eso suena increíble, pero ¿cómo lo hago? ¿Tienes un ejemplo o un enlace a uno? ¡¡Gracias!! – Sam

+0

Ver este ejemplo http://stackoverflow.com/questions/4782364/asp-net-mvc-3-application-using-ninject-entity-framework-4-code-first-ctp-5-pat – Meligy

+0

Comprobar ** Actualizar 2 ** en mi respuesta también. – Meligy