2011-07-21 23 views
17

Por favor perdone mi ignorancia, pero soy muy nuevo en IOC y NinJect. He buscado alto y bajo para soluciones fáciles de entender pero hasta ahora me han eludido.Ninject - constructores vinculantes con argumentos/cadena de conexión de Entity Framework

Hasta ahora tengo el siguiente y todos los trabajos como se esperaba:

private class StandardModule : NinjectModule 
    { 
     public override void Load() 
     { 
     Bind<ILog>().To<NLogLogger>(); // Use NLog 
     Bind<IMyEntityFrameWorkRepository().To<MyEntityFrameWorkRepository>(); 
     } 
    } 

MyEntityFrameWorkRepository continuación, crea su propia EF DbContext a través de una cadena de conexión declarado en app/web.config:

public class MyDbContext : DbContext 
{ 
    public MyDbContext() : base("MyAppConfig") 
    { 
    } 
    ........ 
} 

Sin embargo !! Mi objetivo es algo como esto - Soy consciente de que la sintaxis es "sin sentido" (y yo pensar que pueden tener a la COI MyDbConext también), pero espero que la "pseudo-código" transmite mi deseo:

private class StandardModule : NinjectModule 
{ 
    public override void Load() 
    { 
    Bind<ILog>().To<NLogLogger>(); // Use NLog 

    string mySqlConnectionString = MyApp.GetCommandLineArgument("sqlconn"); // "Data Source=..." 
    Bind<IMyEntityFrameWorkRepository().To<MyEntityFrameWorkRepository>(mySqlConnectionString); 
    } 
} 

................. 

public class MyDbContext : DbContext 
{ 
    public MyDbContext(string sqlConnectionString) : 
     base(sqlConnectionString) // will accept a standard SQL connection string 
    { 
    } 
    ........ 
} 

Realmente agradecería algunos comentarios de los expertos de IOC/NinJect, ya que estoy seguro de que cualquier "patrón" puede ser muy útil en otros escenarios.

Respuesta

21

Puede usar el método .WithConstructorArgument() para especificar argumentos de constructor. El primer argumento debería ser el nombre del parámetro constructor. versiones

public class StandardModule : NinjectModule 
{ 
    public override void Load() 
    { 
     string connectionString = "..."; 
     Bind<IMyEntityFrameWorkRepository().To<MyEntityFrameWorkRepository>() 
      .WithConstructorArgument("sqlConnectionString", connectionString); 
    } 

}

+0

TY tanto! .. He visto este constructo durante mi búsqueda, pero por alguna razón siempre estuve (equivocadamente) preocupado por el "alcance" de 'connectionString' ... pero su breve ejemplo ilustra claramente que solo es el valor de la vinculación lo que es importante. – JcMaltaDev

+0

¿hay alguna manera de hacerlo sin la cadena mágica o para que ninject sepa qué sobrecarga pero decide dónde adquirir los valores? – Maslow

+1

@Maslow No creo que puedas hacerlo en Ninject 2.2 (pero no tomes mi palabra). Sin embargo, debe leer esta [publicación en el blog] (http://www.planetgeek.ch/2011/05/28/ninject-constructor-selection-preview/) que analiza los próximos cambios. – mrydengren

3

más recientes de Ninject permiten deshacerse de las cadenas mágicas en la definición de unión. Algo como esto:

public class StandardModule : NinjectModule 
{ 
    public override void Load() 
    { 
     string connectionString = "..."; 
     Bind<IMyEntityFrameWorkRepository() 
      .ToConstructor(_ => new MyEntityFrameWorkRepository(connectionString); 
    } 
} 

Para los enlaces que implican tipos genéricos (por ejemplo, obligar ISomeService<T>-SomeService<T> y la unión se debe realizar para todos los tipos posibles a la vez), ToConstructor no se puede utilizar (se requiere una nueva expresión), por lo WithConstructorArgument restos el enfoque más simple. Por ejemplo:

Bind(typeof(ISomeService<>)) 
    .To(typeof(SomeService<>)) 
    .WithConstructorArgument("someParam", "someValue"); 
Cuestiones relacionadas