如何从Controller中为Repository的构造函数指定参数?

时间:2013-12-17 18:27:09

标签: asp.net-mvc asp.net-web-api controller repository asp.net-web-api-routing

我对my question here有一个很好的答案,但我不确定我是否可以将这个答案应用到我的项目中,因为我显然需要在我的控制器中使用这样的代码:

return DBConnectionStrings[DBSpecifier].Get(ID, CountToFetch);

...(其中DBConnectionStrings是一个字典)而不是:

return deptsRepository.Get(ID, CountToFetch);

真正的问题/挑战是我需要我的Repositorys的构造函数能够接受arg以便相应地更改DB连接字符串。那些构造函数可以使用前面文章中建议的词典,这样就不会像这样开始:

public DuckbillRepository()
{
    using (var conn = new OleDbConnection(
        @"Provider=Microsoft.Jet.OLEDB.4.0;User ID=NRBQ;Password=NRBQRotPS;Data 
           Source=C:\Platypus\DATA\PlatypusFlipper03.MDB;Jet OLEDB:System 
           database=C:\Platypus\Data\duckbill.mdw"))
    {

......会是这样的:

public DuckbillRepository(string DBToUse)
{
    using (var conn = new OleDbConnection(
        string.Format(@"Provider=Microsoft.Jet.OLEDB.4.0;User 
          ID=NRBQ;Password=NRBQRotPS;Data Source=C:\Platypus\DATA\{0}.MDB;Jet 
          OLEDB:System database=C:\Platypus\Data\duckbill.mdw", DBToUse))
    {

但是,我怎样才能从Controller中为Repository的构造函数指定一个arg(用于填充Repository方法然后查询的数据存储)?目前,典型的控制器如下所示:

static readonly IDuckbillRepository duckbillsRepository = new DuckbillRepository();

public IEnumerable<Duckbill> GetBatchOfDuckbillsByStartingID(int ID, int CountToFetch)
{
    return duckbillsRepository.Get(ID, CountToFetch);
}

目前我能想到的最好的想法/最接近的是我需要这样的东西:

public IEnumerable<Duckbill> GetBatchOfDuckbillsByStartingID(string DBInstance, int ID, int CountToFetch)
{
    IDuckbillRepository duckbillsRepository = new DuckbillRepository(DBInstance);
    return duckbillsRepository.Get(ID, CountToFetch);
}

我是在正确的轨道上,还是在错误的树上狂奔?

2 个答案:

答案 0 :(得分:2)

我想避免使用任何IoC,你有以下选择。

  1. 如果用户只能指定dbInstance作为方法参数,那么只需要为DuckbillRepository类型创建几个构造函数,并只调用适当的构造函数。

    public IEnumerable<Duckbill> GetBatchOfDuckbillsByStartingID(
        string dbInstance, 
        int id, 
        int countToFetch)
    {
        var duckbillsRepository = new DuckbillRepository(dbInstance);
        return duckbillsRepository.Get(id, countToFetch);
    }
    
  2. 如果可以在dbInstance的构造函数中获取DuckbillItemsController,那么我将实现duckbillRepository字段并在构造函数中初始化它。

    /// <summary>
    /// Dependency Injection friendly controller.
    /// </summary>
    public class DuckbillItemsController : ControllerBase
    {
        public readonly DuckbillRepository duckbillRepository;
    
        public IEnumerable<Duckbill> GetBatchOfDuckbillsByStartingID(
            int id, 
            int countToFetch)
        {
            return duckbillRepository.Get(id, countToFetch);
        }
    
        /// <summary>
        ///     <see cref="HttpContext.Current"/> can be a source 
        ///     of 'dbInstance' variable.
        /// </summary>
        public DuckbillItemsController()
            : this(HttpContext.Current.Request["dbInstance"])
        {
        }
    
        public DuckbillItemsController(string dbInstance)
            : this(new DuckbillRepository(dbInstance))
        {
        }
    
        public DuckbillItemsController(DuckbillRepository duckbillRepository)
        {
            this.duckbillRepository = duckbillRepository;
        }
    }
    
  3. 如果可以使用IoC,那么您可以在Passing Arguments IoC中了解Castle Windsor

    var repository = 
        container.Resolve<DuckbillRepository>(new Arguments(new { dbInstance }));
    
      

    此方法对于可用的参数非常有用   组合根,就像你的Program.Main方法一样。虽然它可能看起来   一开始很简单,实际上经常被新人使用   温莎,它的适用性通常非常有限,另一方面   两种方式的使用频率更高。

    1. Registration time - DependsOn和DynamicParameters
    2. Resolution time - 打字的工厂

答案 1 :(得分:0)

我已经制定了一项计划来完成这项工作,但我认为这很复杂,我正在寻找任何一种验证(“是的,这很丑陋,但这就是你所能做的一切”)或更好的想法。

在控制器中,更改此:

static readonly IDuckbillRepository deptsRepository = new DuckbillRepository();

......对此:

static readonly IDuckbillRepository deptsRepository = new DuckbillRepository(string siteVal);

在Repository中,从中更改构造函数:

public DuckbillRepository()
{
    using (var conn = new OleDbConnection(
        @"Provider=Microsoft.ACE.OLEDB.12.0;User ID=NRBQ;Password=NRBQ;Data Source=C:\PlatypusFin\DATA\PlatypusDAT03.MDB;Jet OLEDB:System database=C:\PlatypusFin\Data\nrotps.mdw"))
    {
        using (var cmd = conn.CreateCommand())
        {
            . . .

......对此:

public DuckbillRepository(string siteVal)
{
    string connStr = string.Format(@"Provider=Microsoft.ACE.OLEDB.12.0;User ID=NRBQ;Password=NRBQ;Data Source=C:\PlatypusFin\DATA\{0}.MDB;Jet OLEDB:System database=C:\PlatypusFin\Data\nrotps.mdw", siteVal);
    using (var conn = new OleDbConnection(connStr))
    {
        using (var cmd = conn.CreateCommand())
        {
             . . .