使用简单注入器在构造函数中传递参数

Jos*_*a I 5 .net c# dependency-injection simple-injector asp.net-mvc-4

我在使用简单注入器将参数动态传递给类构造函数时遇到问题。

我有以下代码结构。

控制器示例:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

服务层(在这一层中,我需要传递两个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();
    }
}
Run Code Online (Sandbox Code Playgroud)

存储库层:

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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我的简单注入器初始值设定项类:

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

}
Run Code Online (Sandbox Code Playgroud)

有人对上面的代码有任何解决方案吗?

再次感谢。

Ste*_*ven 6

如果参数固定为特定的封闭泛型类型,则应按如下方式进行注册:

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
Run Code Online (Sandbox Code Playgroud)

如果您的存储库将依赖项与配置值混合在一起,您还可以将上下文注册与开放通用类型的注册混合使用:

// 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>));
}
Run Code Online (Sandbox Code Playgroud)

如果每个请求的连接字符串或存储过程有所不同,您应该更改设计,如此处所述