1

У меня возникла проблема динамического переноса параметра в конструктор класса с помощью простого инжектора.Передача аргумента в конструкторе с использованием простого инжектора

У меня есть следующая структура кода. Пример

Контроллера:.

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 слой (в этом слое, мне нужно передать параметр два конструктора для CheckRepository<T>, реализующая ICheckRepository<T> Как достичь этого с помощью простого инжектора я пытался, но не получить решение? Одним из примеров вокруг, чтобы достичь было бы очень благодарен)

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 слой:.

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(); 
     } 
    } 
} 

Мой простой класс Injector инициализатор:

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 

} 

Кто-нибудь есть решение для приведенного выше кода?

Еще раз спасибо.

+0

Какие значения вы хотите поместить в эти два параметра? У каждого репозитория есть своя строка подключения или хранимая процедура или эти константы конфигурации и равны каждому репозиторию? Можете ли вы обновить свой вопрос примером того, как вы создадите эти репозитории без использования контейнера? – Steven

+0

Его просто строка, и не имеет значения, что именно я вставляю. Но этот параметр строки может отличаться в разных репозиториях. я не получил ваш последний вопрос, который я ищу. Вышеприведенный код объясняет точку, в которой я застрял. –

+0

Это не тот ответ, который вы ищете. Вы ищете способ зарегистрировать это с помощью простого инжектора. Но для того, чтобы помочь вам, вам нужно будет показать, как бы вы открыли эти репозитории вручную, если бы у вас не было Simple Injector. Что-то вроде 'new CheckService (новый FilterRepository (whatgoedhere?)). Пожалуйста, покажите примеры различных репозиториев, которые вы хотите создать. Это дает нам знание того, чего вы пытаетесь достичь, и это позволяет нам сформулировать правильный ответ на ваш вопрос. – Steven

ответ

2

В случае параметры фиксируются в конкретном закрытых тип дженерик, вы должны сделать регистрацию следующим образом:

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 

В случае ваше хранилище смешивает зависимости со значениями конфигурации, вы можете также использовать контекстную регистрацию смешанной с регистрацией открытого общего типа:

// 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>)); 
} 

В случае строка соединения или хранимая процедура изменяется по желанию, вы должны изменить дизайн, как объяснено here.

Смежные вопросы