2011-03-05 17 views
7

¿Cuál es la mejor forma de gestionar el contexto de Entity Framework cuando se utiliza la aplicación MVC?EF Context Management

Estoy usando un patrón de repositorio/servicio.

Editar

Después de mirar a través de algunas de estas preguntas: stackoverflow.com/users/587920/sam-striano, estoy más confundido que antes. Algunos dicen usar el contexto por repositorio, pero ¿qué sucede si quiero usar varios repositorios en un método de controlador?

Y para seguir un buen diseño de separación, ¿cómo se usa UnitOfWork en la aplicación MVC sin hacerlo dependiente de EF? Quiero poder probar mis controladores, modelo, servicios, etc. utilizando un contexto simulado.

+0

Esto fue discutido muchas veces. Por ejemplo, le recomiendo las preguntas de este usuario de la semana pasada: http://stackoverflow.com/users/587920/sam-striano Luego pregunte por un problema concreto que haya encontrado. –

+0

@Lad - Pleas ver mi edición. – Andrew

+0

Esta es una buena publicación que muestra el código para EF Code First Repository Patter con una unidad de trabajo. Utiliza Structuremap como IoC y tiene ejemplos de código para todo. http://stackoverflow.com/questions/4442828/entity-framework-4-ctp-4-ctp-5-generic-repository-pattern-and-unit-testable – Paul

Respuesta

6

Utilice un dependencia Inyector/Inversión del marco de control como:

  1. Ninject
  2. Autofac
  3. StructureMap
  4. Unidad

El uso de un contenedor de IoC, se puede decir que la forma para administrar un único contexto de datos (más comúnmente, por solicitud). Cuando establece el contexto de datos por solicitud, el contenedor automáticamente le dará a cualquier clase que necesita un contexto de datos el mismo contexto de datos por solicitud.

Aquí hay un good article sobre la configuración de Ninject.

Lo que su código será más probable terminar pareciéndose, asumiendo que usted está utilizando un repositorio genérico:

Ninject Módulo:

public class NinjectRegistrationModule : NinjectModule 
{ 
    public override void Load() 
    { 
     Bind<MyDataContext>().ToSelf().InRequestScope(); 
     Bind(typeof(RepositoryImplementation<>)).ToSelf().InRequestScope(); 

    } 
} 

repositorio genérico:

public RepositoryImplementation<T> : IRepository<T> where T : class 
{ 
    MyDataContext _dataContext; 

    public RepositoryImplementation<T>(MyDataContext dataContext) 
    { 
     _dataContext = dataContext; 
    } 

    // bunch of methods that utilize _dataContext 
} 

Clase de servicio:

public class MyServiceClass 
{ 
    IRepository<SomeEntity> _someEntityRepository; 

    public MyServiceClass(IRepository<SomeEntity> someEntityRepository) 
    { 
     _someEntityRepository = someEntityRepository; 
    } 

    // do stuff with _someEntityRepository = someEntityRepository; 
} 

controlador:

public class MyController 
{ 
    MyServiceClass _myServiceClass; 

    public MyController(MyServiceClass myServiceClass) 
    { 
     // Ninject will auto-magically give us a myServiceClass 
     // which will Ninject will inject a repository into MyServiceClass's constructor 
     _myServiceClass = myServiceClass; 
    } 

    public ActionResult MyAction() 
    { 
     // use _myServiceClass to do stuff 
     return View(); 
    } 
} 
+0

Me encanta DI, pero aún debe crear una instancia del ObjectContext desde el repositorio. Por ejemplo, considere las consecuencias de un repositorio configurado como singleton por el contenedor IoC y recibe un ObjectContext como un argumento constructor. – smartcaveman

+0

¡Excelente publicación, gracias! Aunque tengo un par de preguntas. 1) En los ejemplos de Ninject Bind, estoy usando EF4, donde se obtiene el contexto de Bind (). ToSelf(). InRequestScope() ;. La aplicación MVC no debería saber nada de EF, ¿correcto? – Andrew

+0

¿Ha intentado poner el módulo Ninject en su capa de servicio y solo lo hace referencia en su proyecto ASP.NET MVC? – Omar

0

Si su funcionalidad es sencilla, entonces debe crear un nuevo ObjectContext en cada repositorio. Son baratos para crear instancias.

Si esto crea un conflicto, puede usar un patrón de Unidad de trabajo como se sugirió en el comentario.

Le aconsejo que sea extremadamente cauteloso al integrar un ObjectContext o DataContext con un contenedor DI. Muchos no usan el alcance apropiado para su ciclo de vida por defecto.

+0

Tener un nuevo contexto para cada repositorio es algo que funciona solo en escenarios simples. Por lo general, descubrió que desea compartir el contexto entre múltiples repositorios. Esto generalmente se maneja mediante el uso del patrón UnitOfWork. –

+0

¿Algún buen ejemplo del patrón UnitOfWork? – Andrew

+0

http://martinfowler.com/eaaCatalog/unitOfWork.html – smartcaveman

Cuestiones relacionadas