2010-05-14 13 views
8

Tengo una interfaz IGenericRepository<TEntity> where TEntity : IEntity y una implementación GenericRepository<TEntity> where TEntity : Entity.¿Cómo configuro StructureMap para usar un repositorio genérico?

Estoy tratando de inyectar un determinado IGenericRepository<Section> en una clase utilizando StructureMap:

ObjectFactory.Initialize(x => 
     { 
      x.For(typeof(IGenericRepository<>)).Use(typeof(GenericRepository<>)); 
     }); 

Pero cuando trato de usar ObjectFactory.GetInstance<IGenericRepository<Section>>(); me sale:

StructureMap Código de excepción: 202 Sin instancia predeterminada definida para PluginFamily System.Data.Common.DbConnection

¿Alguna idea de por qué esto o qué estoy haciendo mal?

Gracias de antemano,

Simon

Respuesta

3

¿Cuál es su constructor como por GenericRepository<>?

o una de sus dependencias espera un DbConnection que SM no puede crear.

+0

Gracias por eso, mi repositorio genérico está tomando un ObjectContext que no he agregado a través de SM – simonjreid

+0

¿Es esta una respuesta u otra pregunta? Si es una pregunta, ¿por qué está marcada como la respuesta aceptada? –

8

Está recibiendo en el constructor de su GenericRepository una DbConnection, que es una clase abstracta, y no está configurando SM para saber qué clase específica debería usar para ello.

es decir:

ObjectFactory.Initialize(x => 
     { 
      x.For(typeof(DbConnection)).Use(typeof(SqlConnection)); 
      x.For(typeof(IGenericRepository<>)).Use(typeof(GenericRepository<>)); 
     }); 
4

tuve este mismo problema:

tiene un repositorio genérico:

public interface IRepository<TEntity> : IDisposable where TEntity : class 
    { } 

y una aplicación concreta:

public class Repository<TEntity> : IRepository<TEntity> where TEntity : class 
    { } 

que me quería inyectar ed en el constructor de los controladores en tiempo de ejecución en el que el TEntity sería el tipo correspondiente a ese controlador:

public FooBarController(IRepository<FOO_BAR_TYPE> repository) 
     { 
      _repo = repository; 
     } 

el controlador usaría entonces repositorio "_repo" para actualizar el modelo:

// 
// POST: /EmergencyServiceType/Create 
[HttpPost] 
public ActionResult Create(FOO_BAR_TYPE foobar) 
{ 
    if (ModelState.IsValid) 
    {    
     // GetNextSequenceValue() deals with Oracle+EF issue with auto-increment IDs 
     foobar.FOO_BAR_ID = _repo.GetNextSequenceValue(); 
     _repo.Add(foobar); 
     _repo.SaveChanges(); 
     return RedirectToAction("Index"); 
    } 

    return View(foobar); // display the updated Model 
} 

simonjreid me eludió la respuesta: tuve que agregar el ObjectContext a la configuración de StructureMap (el propósito del repositorio era resumir el contexto generado por EntityFramework, que llamé MyContextWrapper).Por lo tanto, debido a que el Repositorio dependía de MyContextWrapper, que a su vez depende de ObjectContext):

// This avoids 'No Default Instance for ...DbConnection' exception 
x.For<System.Data.Objects.ObjectContext>().Use<MyContextWrapper>(); 
x.For<System.Web.Mvc.IController>().Use<Controllers.FooBarController>().Named("foobarcontroller"); // note that Named is required and is Case Sensitive 

Sin embargo, ahora consigo la excepción StructureMap tiempo de ejecución:

StructureMap Código de excepción: 205 Missing solicitada propiedad de instancia " connectionString"

Después de leer un mensaje por Jeremy Miller A Gentle Quickstart (a la derecha en la parte inferior) he encontrado que se puede definir qué argumentos pase al interior de t que el constructor de sus tipos registrados, es decir, que necesitaba para pasar en la cadena de conexión al constructor de la clase MyCustomContext (en este caso es la lista completa de cómo soy inicialización de los ObjectFactory:

string connStr = System.Configuration.ConfigurationManager.ConnectionStrings["MyContextWrapper"].ConnectionString; 
ObjectFactory.Initialize(x => 
      { 
       x.Scan(scan => 
         { 
          // Make sure BUSINESS_DOMAIN assembly is scanned 
          scan.AssemblyContainingType<BUSINESS_DOMAIN.MyContextWrapper>(); 
          scan.TheCallingAssembly(); 
          scan.WithDefaultConventions(); 
         }); 
       // 'connStr' below is a local variable defined above 
       x.For<System.Data.Objects.ObjectContext>() 
        .Use<MyContextWrapper>() 
        .Ctor<string>().Is(connStr); 
       x.For<System.Web.Mvc.IController>().Use<Controllers.FooBarController>().Named("foobarcontroller"); 
      }); 

Y BOOM! Ahora puede tener mi controlador instaniated en tiempo de ejecución por StructureMap y hacer que inyecte una instancia de IRepository ... días felices.

+0

+1: Gracias, hombre. Yo tuve el mismo problema. –

Cuestiones relacionadas