5

Estoy usando Simple Injector para un IOC en una aplicación web MVC 3. Estoy usando RavenDB para el almacenamiento de datos. Hay varias consideraciones sobre el uso de RavenDB en una aplicación mvc 3. He buscado algunos sobre cómo cablear un IoC para usar RavenDB, pero no he descubierto cómo conectar el inyector simple para usar RavenDB. ¿Alguien puede explicar cómo conectar un inyector simple para usar RavenDB en una aplicación web MVC 3?Cómo configurar Simple Ijector IoC para usar RavenDB

gracias.

Respuesta

13

Según el RavenDb tutorial, su aplicación necesita exactamente una instancia de IDocumentStore (por base de datos supongo). A IDocumentStore es seguro para subprocesos. Produce IDocumentSession instancias y representan un unit of work en RavenDB, y esos son no hilo-seguro. Por lo tanto, debe no compartir sesiones entre subprocesos.

La configuración de su contenedor para usar con RavenDb depende principalmente del diseño de la aplicación. La pregunta es: ¿qué quieres inyectar a los consumidores? ¿El IDocumentStore o el IDocumentSession?

Cuando vas con el IDocumentStore, su registro podría tener este aspecto:

// Composition Root 
IDocumentStore store = new DocumentStore 
{ 
    ConnectionStringName = "http://localhost:8080" 
}; 

store.Initialize(); 

container.RegisterSingle<IDocumentStore>(store); 

Un consumidor podría tener este aspecto:

public class ProcessLocationCommandHandler 
    : ICommandHandler<ProcessLocationCommand> 
{ 
    private readonly IDocumentStore store; 

    public ProcessLocationCommandHandler(IDocumentStore store) 
    { 
     this.store = store; 
    } 

    public void Handle(ProcessLocationCommand command) 
    { 
     using (var session = this.store.OpenSession()) 
     { 
      session.Store(command.Location); 

      session.SaveChanges(); 
     }    
    } 
} 

Debido a que se inyecta el IDocumentStore, los consumidores son ellos mismos responsables de gestionar la sesión: creación, almacenamiento y eliminación. Esto es muy conveniente para aplicaciones pequeñas, o por ejemplo cuando se oculta la base de datos RavenDb detrás de un repository, donde se llama al session.SaveChanges() dentro del método repository.Save(entity).

Sin embargo, este tipo de uso de una unidad de trabajo me resultó problemático para aplicaciones de mayor tamaño. Entonces, lo que puede hacer en su lugar, es inyectar el IDocumentSession en los consumidores. En ese caso, el registro podría tener este aspecto:

IDocumentStore store = new DocumentStore 
{ 
    ConnectionStringName = "http://localhost:8080" 
}; 

store.Initialize(); 

// Register the IDocumentSession per web request 
// (will automatically be disposed when the request ends). 
container.RegisterPerWebRequest<IDocumentSession>(
    () => store.OpenSession()); 

en cuenta que necesita la Simple Injector ASP.NET Integration NuGet package (o incluir el SimpleInjector.Integration.Web.dll a su proyecto, que se incluye en la descarga por defecto) para ser capaz de usar el método de extensión RegisterPerWebRequest.

La pregunta ahora es: ¿dónde llamar al session.SaveChanges()?

Existe una pregunta sobre el registro de unidades de trabajos por solicitud web, que también aborda la pregunta sobre SaveChanges. Por favor, eche un buen vistazo a esta respuesta: One DbContext per web request…why?. Cuando reemplace las palabras DbContext con IDocumentSession y DbContextFactory con IDocumentStore, podrá leerlo en el contexto de RavenDb. Tenga en cuenta que tal vez la noción de transacciones comerciales o transacciones en general no son tan importantes cuando se trabaja con RavenDb, pero sinceramente no lo sé. Esto es algo que tendrás que descubrir por ti mismo.

Cuestiones relacionadas