2

我有一個很好的答案my question here,但我不知道我是否可以申請這個問題的答案我的項目,因爲我顯然需要使用代碼這樣的事情在我的控制器:如何從Controller中爲存儲庫的構造函數指定參數?

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

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

return deptsRepository.Get(ID, CountToFetch); 

真正的問題/挑戰是,我需要我的Repositorys'建設者能夠接受ARG,以便相應地更改數據庫連接字符串。然後,這些構造函數可以使用字典建議在先前的帖子中,以便開始而不是像這樣:

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

使用像NInject一個DI容器。事實上,通常的做法不是將arg傳遞給資源庫的構造函數,而是將整個資源庫對象傳遞給控制器​​。 –

+0

客戶端通過http傳遞一個倉庫對象給控制器?這不是問題的過度複雜化,還有違反DRY和潛在危險的傳播應該是服務器特定的實現細節?我不是說你錯了,我只是感到驚訝/困惑。 –

+1

不,客戶端將字符串傳遞給服務器。 NInject工廠使用字符串來實例化回購並將其傳遞給控制器​​。 –

回答

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. 如果有可能獲得在DuckbillItemsController的構造dbInstance話,我會實現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; 
        } 
    } 
    

如果是正常使用的IoC,那麼你可以閱讀Castle Windsor的IoC約Passing Arguments

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

這種方法對於那些在 組合物根可用,像您的Program.Main方法參數是有用的。儘管在開始時看起來很簡單,實際上經常被溫莎的新手 使用,但它的適用性通常是相當有限的,而其他方法則更經常使用兩種方法。

  1. Registration time - DependsOn和DynamicParameters
  2. Resolution time - 類型的工廠
+0

+1深思熟慮 –

0

我已經制定了一個計劃來完成這項工作,但考慮到這個問題,我正在尋找驗證(「是的,這很醜陋,但這是關於你所能做的所有事情」)或更好的主意。

在控制器中,更改此:

static readonly IDuckbillRepository deptsRepository = new DuckbillRepository(); 

...這樣的:

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

在資源庫,從這個改變的構造函數:

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()) 
     { 
      . . . 

.. .to:

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()) 
     { 
      . . . 
+1

使用靜態回購將意味着它將在所有線程之間共享 - 這可能不是一個好主意,具體取決於回購緩存是否連接(即每個呼叫都從連接池獲取新連接)。 – StuartLC

相關問題