【问题标题】:Passing argument in constructor using Simple Injector使用简单注入器在构造函数中传递参数
【发布时间】:2016-06-01 16:59:43
【问题描述】:

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

我有以下代码结构。

控制器示例:

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

服务层(在这一层中,我需要为实现ICheckRepository<T>CheckRepository<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();
        }
    }
}

我的简单注入器初始化类:

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

}

上面的代码有人有解决办法吗?

再次感谢。

【问题讨论】:

  • 你想在这两个参数中输入什么值?每个存储库是否都有自己的连接字符串或存储过程,或者这些配置常量是否等于每个存储库?您能否通过一个示例来更新您的问题,说明如何在不使用容器的情况下创建这些存储库?
  • 它只是一个字符串,我输入的内容并不重要。但是这些字符串参数可能会因不同的存储库而异。我没有得到你的最后一个问题,因为这就是我正在寻找的答案。上面的代码解释到我被卡住了。
  • 这不是您要寻找的答案。您正在寻找一种使用 Simple Injector 进行注册的方法。但是,如果您没有 Simple Injector,您必须向我们展示如何手动更新这些存储库。像new CheckService(new FilterRepository&lt;CheckType&gt;(whatgoedhere?)) 这样的东西。请显示您想要创建的不同存储库的示例。这让我们了解您想要达到的目标,并让我们能够为您的问题制定正确的答案。
  • 我知道你在找什么,我可能不知道你在找什么。我认为你只是想进入正方形。我告诉你它只是一个字符串。我真的不明白你在看什么。你不能指望我为你复制粘贴整个项目。
  • 问题的答案完全取决于您希望注入的数据。例如,如果每个请求的数据都发生了变化,那么您的解决方案首先是错误的,正如here 所解释的那样。如果每个封闭类型的值发生变化,则必须像对待非泛型类型一样单独注册每个封闭类型。

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


【解决方案1】:

如果参数被固定为特定的封闭泛型,你应该进行如下注册:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-11-24
    • 1970-01-01
    • 2014-03-08
    • 1970-01-01
    • 1970-01-01
    • 2010-11-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多