2012-01-25 35 views
1

這是一個白癡問題,所以你必須原諒我,但我是一個自學成才的程序員,而且乾淨整潔的架構經常讓我感到困惑。我正在通過這樣的問題來學習:)使用接口鬆散地連接NoSQL提供程序

所以我必須編寫一個數據訪問類來與NoSQL數據庫進行交互。問題在於,我們希望在以後更改我們的NoSQL平臺,因此我需要在我的類和實際的數據訪問之間儘可能鬆散地實現這種依賴關係。

草圖繪製了這一點,在我的腦子裏,我想通做到這一點的最好辦法是,將界面有點像這樣:

public interface INoSql 
{ 
    string ServerLocation 
    { 
     get; set; 
    } 

    string DatabaseName 
    { 
     get; set; 
    } 

    string CollectionName 
    { 
     get; set; 
    } 

    void SaveChanges(List<NoSqlItem> nsCollection); 
} 

然後使該是這樣的特定數據訪問類MongoDB的

public class MongoDBConnection : IRealtimeDataAccess 
{ 
    string ServerLocation 
    { 
     get; set; 
    } 

    string DatabaseName 
    { 
     get; set; 
    } 

    string CollectionName 
    { 
     get; set; 
    } 

    public void SaveChanges(List<NoSqlItem> nsCollection) 
    { 
     MongoServer mServer = MongoServer.Create(this.ServerLocation); 
     MongoDatabase mDb = mServer.GetDatabase(this.DatabaseName); 
     MongoCollection<BsonDocument> mDbItemCollection = mDb.GetCollection<BsonDocument>(this.CollectionName); 
     mDbItemCollection.InsertBatch(nsCollection); 
    } 

簡單到目前爲止 - 所有我需要做的就是使用數據訪問層只引用​​的接口,然後如果我們想換到另一個NoSQL的供應商所有我需要做的就是重新確保任何類 - 爲實現相同接口的新數據訪問組件編寫代碼 對?好吧,考慮一下,問題出現在我想使用它的時候。因爲這顯然不起作用:

INoSql noSQLConnection = new INoSql; 

因爲你不能實例化一個接口。

那麼有什麼解決方案來保持我的代碼漂亮和鬆散?它周圍閱讀看起來好像一個答案是,其注入的構造函數:

public class MyClass 
{ 
    private INoSql NoSql; 

    public myClass(INoSql NoSql) 
    { 
     this.NoSql = NoSql; 
    } 
} 

這看起來整潔,但不是這只是移動的問題?因爲當你創建MyClass時,你將不得不實例化一個實現INoSql的具體版本,是的,那必須是一個MongoDBConnection--或者其他什麼 - 而不是鬆散耦合的類?

顯然我錯過了什麼,但什麼?還有其他解決這個常見問題的方法嗎?

乾杯, 馬特

回答

5

你不需要重新發明輪子。

在我humild認爲,庫設計模式將做的工作:

UPDATE

我忘了「怎麼了一部分獲得接口實現「 。

您將遵循存儲庫模式,創建一個接口或抽象類,稍後將爲您的NoSQL對象源的特定實現。

爲了得到正確的執行,其他人指出,你可以使用一些框架,如:

最後,我想建議你Common Service Locator是ord的好朋友呃做沒有直接依賴於特定的IoC/DI框架:

+0

感謝你 - 有趣的閱讀。最後,我決定Respository模式對我的需求有點誇張,因爲換出可能永遠不會發生,理想情況下我不想將另一個外部庫添加到我們的代碼中。我用工廠方法獲得了大部分所需的東西。但是,您的答案是有用的,相關的,並使我走上正確的道路,因此值得一試。 –

+1

@MattThrower沒問題。順便說一下,您不需要考慮_repository pattern_「換出」。它是絕對抽象對象源的最佳解決方案之一,因此您可以避免依賴OR/M框架或簡單的ADO.NET,_repository pattern_更加「業務層友好」。但我對您的實際需求一無所知,我希望這些信息能成爲您未來項目的靈感源泉! :) –

2

查找到IoC容器,像Castle WindsorSpringFramework.netStructureMap。這是他們設計要解決的問題。

+1

嘿;)但IoC解決了檢索正確的實現,但IoC本身不是抽象對象源的解決方案。 –

+0

沒關係,我忘了他要求的如何獲得一些接口的實現細節...對不起:) –

+1

不,我們鼓勵在這裏辯論,它的罰款。恕我直言,他將需要一些比存儲庫模式更復雜的東西,因爲(正如@威廉羅格斯指出的那樣),他還需要解決各種驅動程序的硬件依賴問題,一旦出現問題動態加載程序集,最好將其交給已經解決問題的專業人員。 –

1

您可以使用Unity或其他IoC容器來註冊和實例化實現接口的對象。您的代碼看起來是這樣的:

INoSql noSQLConnection = UnityContainer.Resolve<INoSql>(); 

Microsoft Unity Framework

2

我同意馬蒂亞斯關於Repository模式。你試圖解決的另一個問題是對數據庫提供者(在你的例子中是MongoDB)的依賴性很強。儘管真正能夠交換數據訪問並不像將其隱藏在接口後面那麼簡單,但是一種技術稱爲依賴注入,並且您正在MyClass代碼中使用它的一種形式(構造函數注入)。

這裏的依賴注入的概述:http://jamesshore.com/Blog/Dependency-Injection-Demystified.html

你是正確的,它推動了硬依賴性的問題出來了之類的到別的地方。幸運的是,有一些工具可以幫助我們連接並管理這些後來想要注入和使用的依賴關係。這些知道是控制容器的反轉,並且它們允許您指定和解決代碼中的依賴關係,並且通常在配置文件中。下面是關於他們的SO問題:

https://stackoverflow.com/questions/2515124/whats-the-simplest-ioc-container-for-c

Autofac,StructureMap,和Unity是我曾經成功使用。

希望這會有所幫助!

相關問題