2012-09-03 19 views
8

Estoy usando Ninject como contenedor IoC en mi proyecto. Tengo la siguiente clase:Unión basada en convenciones de argumentos de cadena de constructor con Ninject

public class SomeRepository:ISomeRepository 
{ 
    public SomeRepository(string someDatabaseConnectionString) 
    { 
     // some code here.. 
    } 
} 

En mi archivo de configuración de la aplicación tengo una cadena de conexión llamada "someDatabase". Por defecto, el uno debe añadir siguiente configuración con el fin de inyectar esta cadena de conexión en el constructor:

kernel.Bind<ISomeRepository>() 
    .To<SomeRepository>() 
    .WithConstructorArgument("someDatabaseConnectionString", connString); 

pero quiero poner en práctica convencional basada unión de dichas cadenas. Los valores para todos los parámetros de constructor de tipo de cadena que los nombres finalizan con "ConnectionString" deben tomarse de la sección de configuración connectionStrings de la aplicación e inyectarse automáticamente. Quiero implementar una convención similar para la sección appSettings también. Este enfoque se describe en mayor detalle en el artículo "Primitive Dependencies" de Mark Seeman (sección "Convenciones para primitivos"). El contenedor de Castle Windsor se usó en ejemplos.

¿Es posible implementar tales convenciones usando Ninject y cuál es la mejor manera de hacerlo? Ya he probado ninject.extensions.conventions pero parece que no tiene esa funcionalidad, ¿verdad?

+0

¿Se puede usar ConfigurationManager.AppSettings ["someDatabaseConnectionString"]? – Ben

+0

Actualmente estoy usando ConfigurationManager.AppSettings ["someDatabaseConnectionString"]. Pero imagine que tiene 20 o más clases que dependen de las cadenas de conexión. No quiero escribir una regla específica para cada una de estas clases, quiero inyectar dependencias automáticamente. –

Respuesta

1

No parece que ese tipo de enlaces basados ​​en convenciones sea posible con Ninject en este momento. I had a similar question here y la sugerencia era hacer una interfaz para devolver la cadena de conexión y tener eso como el parámetro. Sin embargo, eso podría ser tedioso para muchas cadenas de conexión diferentes.

Esto es sólo un pensamiento, pero ¿podría tener un IConnectionStringProvider<T> que podría usar el reflejo para obtener el nombre de T y buscar la configuración de la aplicación de esa manera? Tal como esto:

public class ConnectionStringProvider<T> : IConnectionStringProvider<T> 
{ 
    public string Value 
    { 
     // use reflection to get name of T 
     // look up connection string based on the name 
     // return the connection string 
    } 
} 
... 
public class SomeRepository:ISomeRepository 
{ 
    public SomeRepository(IConnectionStringProvider<SomeRepository> connectionStringProvider) 
    { 
     this.connectionString = connectionStringProvider.Value; 
    } 
} 

Además, si eso no funciona, usted podría tener un no genérico IConnectionStringProvider que tiene un tipo como argumento:

public class ConnectionStringProvider : IConnectionStringProvider 
{ 
    public string GetValueFor(Type type) 
    { 
     // use reflection to get name of type 
     // look up connection string based on the name 
     // return the connection string 
    } 
} 
... 
public class SomeRepository:ISomeRepository 
{ 
    public SomeRepository(IConnectionStringProvider connectionStringProvider) 
    { 
     this.connectionString = connectionStringProvider.GetValueFor(this.GetType()); 
    } 
} 

Si una de estas obras a como lo hacen tienen la ventaja de que deben funcionar con cualquier contenedor DI.

Cuestiones relacionadas