1

Ich habe Probleme bei der Übergabe von Parametern dynamisch an den Klassenkonstruktor mit einem einfachen Injektor.Übergeben von Argument im Konstruktor mit Simple Injector

Ich habe folgenden Code Struktur.

-Controller. Beispiel:

public class HomeController : Controller 
{ 
    private readonly ICheckService _checkService; 

    public HomeController(ICheckService checkService) 
    { 
     _checkService= checkService; 
    } 

    // GET: Home 
    public ActionResult Index() 
    { 
     var list = _checkService.GetAll(); 
     return View(list); 
    } 
} 

Service-Schicht (in dieser Schicht ich die beiden Konstruktorparameter für CheckRepository<T> übergeben muß, die ICheckRepository<T> implementiert Wie erreiche ich diesen mit einfachen Injektor ich versuchte, aber nicht Lösung zu bekommen? um ein Beispiel, um dankbar wäre zu erreichen, wirklich)

public interface ICheckService 
{ 
     List<CheckType> GetAll(); 
} 

public class CheckService : ICheckService 
{ 
    private readonly ICheckRepository<CheckType> _checkRepository; 

    public CheckService(ICheckRepository<CheckType> checkRepository) 
    { 
     _checkRepository= checkRepository; 
    } 

    public List<T> GetAll() 
    { 
     return _checkRepository.GetAll().ToList(); 
    } 
} 

Repository-Schicht.

public abstract class RepositoryBase<T> where T : class 
{ 
    public string Types { get; set; } 
    public string Segment { get; set; } 

    public RepositoryBase(string type) 
    { 
     Types = type; 
    } 

    public RepositoryBase(string type, string segment) 
    { 
     Types = type; 
     Segment = segment; 
    } 
} 

public interface ICheckRepository<T> where T : class 
{ 
    IEnumerable<T> GetAll(); 
} 

public class CheckRepository<T> : RepositoryBase<T>, ICheckRepository<T> where T : class 
{ 
    public CheckRepository(string types, string segment) 
     : base(types, segment) 
    { 

    } 

    public IEnumerable<T> GetAll() 
    { 
     var list = new List<T>(); 
     using (DbAccess dbAccess = new DbAccess(ConnectionString, DatabaseType.SqlServer)) 
     { 
      return dbAccess.ExecuteReader<T>(StoredProc, CommandType.StoredProcedure).ToList(); 
     } 
    } 
} 

Meine Einfache Injector initializer Klasse:

public static void InitializeInjector() 
{ 
    var container = new Container(); 

    InitializeContainer(container); 

    container.RegisterMvcControllers(Assembly.GetExecutingAssembly()); 
    container.RegisterMvcIntegratedFilterProvider(); 
    container.Verify(); 

    DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container)); 
} 

private static void InitializeContainer(Container container) 
{ 
    container.Register(typeof(IFilterRepository<>), typeof(FilterRepository<>)); 
    //Here is where I am struggling to bind dynamic constructor parameter registering 

} 

jemand für den obigen Code jede Lösung Hat?

Nochmals vielen Dank.

+0

Welche Werte möchten Sie in diese beiden Parameter eingeben? Verfügt jedes Repository über eine eigene Verbindungszeichenfolge oder eine gespeicherte Prozedur oder sind diese Konfigurationskonstanten identisch mit jedem Repository? Können Sie Ihre Frage mit einem Beispiel aktualisieren, wie Sie diese Repositorys ohne Verwendung eines Containers erstellen würden? – Steven

+0

Es ist nur eine Zeichenfolge und es spielt keine Rolle, was genau ich eingegeben habe. Aber diese String-Parameter können mit verschiedenen Repository variieren. Ich habe deine letzte Frage nicht bekommen, denn das ist die Antwort, die ich suche. Der Code oben erklärt bis zu dem Punkt, wo ich stecken geblieben bin. –

+0

Das ist nicht die Antwort, die Sie suchen. Sie suchen nach einer Möglichkeit, dies bei Simple Injector zu registrieren. Aber damit wir Ihnen helfen können, müssen Sie uns zeigen, wie Sie diese Repositories von Hand neu gemacht hätten, wenn Sie keinen Simple Injector hätten. Etwas wie 'neuer CheckService (neues FilterRepository (whatgoedhere?))'. Zeigen Sie Beispiele für die verschiedenen Repositorys an, die Sie erstellen möchten. Dies gibt uns das Wissen von dem, was Sie erreichen wollen, und es ermöglicht uns, die richtige Antwort auf Ihre Frage zu formulieren. – Steven

Antwort

2

Falls die Parameter der spezifischen fixiert sind geschlossene generische Typen, sollten Sie die Eintragungen machen, wie folgt:

c.Register<ICheckRepo<Customer>>(() => new CheckRepository<Customer>(constr, "cust_sp")); 
c.Register<ICheckRepo<Order>>(() => new CheckRepository<Order>(constr, "order_sp")); 
c.Register<ICheckRepo<Product>>(() => new CheckRepository<Product>(constr, "prod_sp")); 
// more registrations here 

Wenn Ihr Repository Abhängigkeiten mit Konfigurationswerten mischt, können Sie auch kontextuellen Registrierung verwenden gemischt mit der Registrierung des offenen generischen Typ:

// Registrations 
// One registration for the open generic type 
c.Register(typeof(ICheckRepository<>), typeof(CheckRepository<>)); 

// One registration for the connection string (assuming you only have one) 
container.RegisterConditional(typeof(string), CreateStringConstant(constr), 
    c => c.Consumer.Target.Name == "connectionString"); 

// Conditional registrations for each closed ICheckRepository<T> 
RegisterStoredProcForCheckRepository<Customer>("cuts_sp"); 
RegisterStoredProcForCheckRepository<Order>("order_sp"); 
RegisterStoredProcForCheckRepository<Product>("prod_sp"); 
// more registrations here 

// Helper methods 
Registration CreateStringConstant(string value) => 
    Lifestyle.Singleton.CreateRegistration(typeof(string),() => value, container); 

void RegisterStoredProcForCheckRepository<TEntity>(string spName) { 
    container.RegisterConditional(typeof(string), CreateStringConstant(container, spName), 
     c => c.Consumer.Target.Name == "segment" 
      && c.Contumer.ImplementationType == typeof(CheckRepository<TEntity>)); 
} 

Falls die Verbindungszeichenfolge oder eine gespeicherte Prozedur pro Anforderung variiert, sollten Sie das Design ändern, wie here erläutert.