2010-05-14 13 views
8

Ho un'interfaccia IGenericRepository<TEntity> where TEntity : IEntity e un'implementazione GenericRepository<TEntity> where TEntity : Entity.Come configurare StructureMap per utilizzare un repository generico?

Sto cercando di iniettare una specifica IGenericRepository<Section> in una classe utilizzando StructureMap:

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

Ma quando provo ad usare ObjectFactory.GetInstance<IGenericRepository<Section>>(); ottengo:

StructureMap Codice di eccezione: 202 No default grado ha definito per PluginFamily System.Data.Common.DbConnection

Qualche idea perché questo è o cosa sto facendo male?

Grazie in anticipo,

Simon

risposta

3

Qual è il suo costruttore come ad GenericRepository<>?

Questo o una delle sue dipendenze si aspetta un DbConnection che SM non può creare.

+0

Grazie per questo, il mio repository generico sta prendendo un ObjectContext che non ho aggiunto tramite SM – simonjreid

+0

Is Questa è una risposta o un'altra domanda? Se è una domanda, perché è contrassegnata come la risposta accettata? –

8

Si sta ricevendo nel costruttore del tuo GenericRepository una DbConnection, che è una classe astratta, e non sta configurando SM per sapere quale classe specifica dovrebbe usare per essa.

cioè:

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

Ho avuto questo problema esattamente lo stesso:

avere un repository generico:

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

e una concreta attuazione:

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

che ho voluto iniettare Ed al costruttore dei controllori in fase di esecuzione in cui l'TEntity sarebbe il modello relativo a quel controller:

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

il controller sarebbe quindi utilizzare Repository "_repo" per aggiornare il Modello:

// 
// 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 ellude alla risposta per me: è stato necessario aggiungere ObjectContext alla configurazione di StructureMap (lo scopo del repository era quello di racchiudere il contesto generato da EntityFramework, che ho chiamato MyContextWrapper.Quindi perché il repository dipendeva MyContextWrapper, che a sua volta dipende da 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 

Tuttavia, ora ho l'eccezione StructureMap runtime:

StructureMap Codice di eccezione: 205 mancante proprietà di istanza richiesto " ConnectionString"

Dopo aver letto un post di Jeremy Miller A Gentle Quickstart (a destra in basso) ho scoperto che è possibile definire quali argomenti da passare in t egli costruttore dei tuoi tipi registrati cioè avevo bisogno di passare nella stringa di connessione al costruttore della classe MyCustomContext (qui è la lista completa di come sto inizializzazione del 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"); 
      }); 

E BOOM! Ora il Structure Controller può essere istaniato in runtime da StructureMap e farlo in modo da iniettare un'istanza di IRepository ... giorni felici.

+0

+1: Grazie, amico. Ho avuto lo stesso problema. –

Problemi correlati