2009-07-21 12 views
11

he empezado a utilizar Ninject 2 (descargar desde Github ayer que incluye el proyecto de ampliación MVC) con un proyecto basado en las siguientes tecnologías:¿Cómo puedo obtener Ninject 2 para usar el constructor sin parámetros para LINQ to SQL DataContext?

  • .Net 3.5 SP1
  • ASP.NET MVC 1.0
  • LINQ a SQL

nada mágico aquí - tengo un par de interfaces de repositorio (nombrados como IEntityRepository) que se implementan utilizando LINQ to SQL en el código de tiempo de ejecución (y utilizando una tabla hash en el código de prueba de unidad). Cada uno de estos repositorios necesita una instancia del DataContext de LINQ a SQL para hablar con la base de datos, por lo que es un parámetro de constructor en las clases de repositorio concretas. La unión está configurado como esto:

Kernel.Bind<MyDataContext>().ToSelf().InRequestScope(); 

La razón de esto es que quiero ser capaz de compartir entidades entre diferentes repositorios si debería llegara a necesitar más de ellos, y con el LINQ a SQL DataContext unidad de filosofía del trabajo, parece tener sentido para mí crear uno por HttpRequest.

Normalmente utilizo el constructor sin parámetros para MyDataContext. No lo veo como un riesgo porque se usa para un proyecto interno en un sistema de prueba, por lo que la cadena de conexión "incorporada" en el contexto de datos es inofensiva. Sin embargo, dado que Ninject 2 es "codicioso" y quiere el constructor con los parámetros MOST, y realmente no puedo pegar el parámetro [Inject] en el código generado de manera significativa, me aparece un error cada vez que Ninject intenta crear uno de mis controladores (que necesita un repositorio, que necesita el contexto de datos).

He visto mención de IConstructorScorer y la capacidad de hacer una "invertida" que siempre usaría el constructor con los parámetros LEAST, pero una vez más, esto cambiaría la forma en que funciona la inyección para todo lo demás - el comportamiento predeterminado es probablemente lo que quiero para todo menos el contexto de datos.

Entonces, ¿hay una manera bonita y clara de especificar que este enlace (y solo este enlace) debería usar un constructor específico? ¿Podemos hacer lo mismo con los proveedores que en Ninject 1, y tal vez suministrar nuestra propia "fábrica"? ¿O debería ceder y tratar de introducir parámetros en el contexto de datos que tengan sentido?

Respuesta

6

Lo he entendido: es bastante fácil de encuadernar con un proveedor;

Kernel.Bind<MyDataContext>().ToProvider<ContextProvider>().InRequestScope(); 

Ninject ahora llamará a mi ContextProvider cuando sea necesario para construir uno de esos molestos objetos DataContext. Así es como se ve mi clase de proveedor:

public class ContextProvider : IProvider 
{ 
    #region IProvider Members 

    public object Create(IContext context) 
    { 
     return new MyDataContext(); 
    } 

    public Type Type 
    { 
     get { throw new NotImplementedException(); } 
    } 

    #endregion 
} 

Parece que me salí con la mía - funciona bien. :)

7

Creo que se puede utilizar también 'ToMethod' vinculante para evitar la aplicación de proveedor personalizado, así es como yo uso:

Kernel.Bind<MyDataConext>().ToMethod(c => new MyDataContext()) 
+2

Para ser completa, me gustaría añadir el 'InRequestScope()' para asegurar la la vida útil del DataContext tiene un alcance adecuado. –