2009-11-25 15 views
8

Soy muy nuevo en Ninject y estoy probando Ninject 2 con MVC y Linq. Tengo una clase SqlProductRepository y todo lo que quiero saber es cuál es la mejor manera de pasar la conexión de la cadena en el constructor si estoy inyectando el objeto Repository en el controlador.Cadenas de conexión y ninject

public class SqlProductRepository:IProductRepository 
{ 
    private Table<Product> productsTable; 

    public SqlProductRepository(string connectionString) 
    { 
     productsTable = (new DataContext(connectionString)).GetTable<Product>(); 
    } 

    public IQueryable<Product> Products 
    { 
     get { return productsTable; } 
    } 
} 

Ésta es mi clase ProductController donde yo estoy inyectando el repositorio:

public class ProductsController : Controller 
{ 
    private int pageSize = 4; 
    public int PageSize { get { return pageSize; } set { pageSize = value; } } 

    IProductRepository _productsRepository; 

    [Inject] 
    public ProductsController(IProductRepository productRepository) 
    { 
     _productsRepository = productRepository; 
    } 

    public ViewResult List(int page) 
    { 
     return View(_productsRepository.Products 
             .Skip((page - 1) * pageSize) 
             .Take(pageSize) 
             .ToList() 
        ); 
    } 
} 

Puede alguien por favor me guía con respecto a esto?

Respuesta

15

Puede configurarlo en su unión

 

_kernel.Bind<IProductRepository>() 
     .To<SqlProductRepository>() 
     .WithConstructorArgument("connectionString",yourConnectionString); 
5

que estás haciendo:

new DataContext(connectionString) 

en el código - esta es la Newing y la unión a las clases que está tratando de empujar fuera de su código mediante el uso de un contenedor DI. Por lo menos, considere agregar una interfaz IConnectionStringSelector o algo así. No desea tener 20 Bind llamadas para 20 repositorios; desea una abstracción de nivel superior.

Sugeriría que la mejor solución es que debe exigir un IDataContext o un IDataContextFactory en el constructor y dejar que eso le preocupe.

2

Puede suministrar la cadena de conexión como un argumento de constructor al vincular SqlProductRepository a la interfaz IProductRepository.

public class LinqToSqlModule : NinjectModule 
{ 
    public override void Load() 
    { 
     Bind<IProductRepository>().To<SqlProductRepository>() 
      .WithConstructorArgument(connectionString, "connectionstring"); 
    } 
} 

Yo sugeriría un enfoque ligeramente diferente. En primer lugar, es posible que desee crear un enlace para la clase DataContext en el kernel. Puede hacerlo utilizando una clase de proveedor para crear su DataContext pasando la cadena de conexión como argumento para su constructor. A continuación, enlaza el DataContext con el DataContextProvider.

public class DataContextProvider : Provider<DataContext> 
{ 
    protected override DataContext CreateInstance(IContext context) 
    { 
     string connectionString = "connectionstring"; 
     return new DataContext(connectionString); 
    } 
} 

public class LinqToSqlModule : NinjectModule 
{ 
    public override void Load() 
    { 
     Bind<DataContext>().ToProvider<DataContextProvider>(); 
     Bind<IProductRepository>().To<SqlProductRepository>(); 
    } 
} 

Siguiente modificar el constructor de la clase SqlProductRepository para aceptar un objeto DataContext lugar.

public class SqlProductRepository : IProductRepository 
{ 
    private readonly DataContext context; 

    public ProductRepository(DataContext context) 
    { 
     this.context = context; 
    } 

    public IQueryable<Product> Products 
    { 
     get { return context.GetTable<Product>(); } 
    } 
} 

Por cierto que no tiene que adornar su constructor con el atributo Inject. Ninject seleccionará el constructor con la mayoría de los parámetros por defecto.

0

Por favor remítase a continuación complemento código:

//Bind the default connection string 
    public void BindDataContext() 
    { 
     ConstructorArgument parameter = new ConstructorArgument("connectionString", "[Config Value]"); 
     Bind<DataContext>().ToSelf().InRequestScope().WithParameter(parameter); 
    } 
    //Re-Bind the connection string (in case of multi-tenant architecture) 
    public void ReBindDataContext(string cn) 
    { 
     ConstructorArgument parameter = new ConstructorArgument("connectionString", cn); 
     Rebind<DataContext>().ToSelf().InRequestScope().WithParameter(parameter); 
    } 

Para obtener más información, visite el acoplamiento abajo

MVC3, Ninject and Ninject.MVC3 problem

Cuestiones relacionadas