使用Simple Injector

时间:2016-06-01 16:59:43

标签: c# .net asp.net-mvc-4 dependency-injection simple-injector

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

我有以下代码结构。

控制器示例:

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

服务层(在这一层我需要传递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();
    }
}

存储库层:

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

My Simple 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

}

有没有人对上述代码有任何解决方案?

再次感谢。

1 个答案:

答案 0 :(得分: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

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

// 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所述。