2012-01-25 11 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; 
    } 
} 

:1つの答えは、コンストラクタにそれを注入することであるかのように、それを中心に読んで見えますか?したがって、MyClassを作成するときにINoSqlを実装する具体的なバージョンのインスタンスを生成する必要があるため、疎結合クラスの代わりにMongoDBConnectionなどが必要になります。

明らかに私は何かを逃しましたが、何ですか?そして、この共通の問題に対する他の解決策がありますか?

乾杯、 マット

答えて

5

あなたは、車輪を再発明する必要はありません。私humildの意見では

リポジトリデザインパターンが仕事をする:

UPDATE

は、私がどのように「の部分を忘れてしまいましたインターフェイスの実装を取得する " 。

あなたは、インターフェイスまたは抽象クラスを作成し、後でNoSQLオブジェクトソースの特定の実装を作成すると、リポジトリパターンに従います。右の実装を取得するために

、他が指摘したように、あなたには、いくつかのフレームワークのように使用することができます。

最後に、共通サービスロケータはordの良い友達です特定のIoC/DIフレームワークへの直接の依存関係がありませんするER:

+0

ありがとうございます - 興味深い読書。結局私は、スワップアウトが起こらないかもしれないので、私のニーズには少し余裕があり、理想的に私たちのコードに別の外部ライブラリを追加したくなかったということで、リポジトリのパターンが少し誇張されていると判断しました。私は工場の方法で必要なもののほとんどを得ました。しかし、あなたの答えは有益で、関連性があり、適切な道筋に私を置くことができます。 –

+1

@MattThrower問題ありません。ちなみに、 "スワップアウト"のための_repository pattern_について考える必要はありません。これは絶対的抽象オブジェクトソースのための最良のソリューションの1つで、OR/Mフレームワークまたは単なるADO.NETへの依存を避け、_repository pattern_はより "ビジネスレイヤに優しい"ものです。しかし、私はあなたの実際の要件について何も知らないし、私はこの情報があなたの将来のプロジェクトでインスピレーションの良い源になることを願っています! :) –

2

Castle WindsorSpringFramework.net、およびStructureMapのような、IoCコンテナの中に見て。彼らが解決しようとしている問題の種類。

+1

Hey;)しかし、IoCは適切な実装の取得を解決しますが、IoC自体はオブジェクトソースを抽象化するためのソリューションではありません。 –

+0

心配しないで、私は彼がいくつかのインターフェイスの実装を取得する方法を尋ねている詳細を忘れました...申し訳ありません:) –

+1

いいえ、私たちはここでその議論を奨励します。 IMHO、彼はリポジトリパターンより洗練されたものを必要とするでしょう(@WillRogersが指摘するように)、彼はまた、様々なドライバのアセンブリに対するハード依存性の問題に取り組む必要があります。動的にアセンブリをロードするには、すでに問題を解決しているプロに任せておく方がよいでしょう。 –

1

インターフェイスを実装するオブジェクトを登録およびインスタンス化するために、Unityまたは別のIoCコンテナを使用できます。私は、リポジトリのパターンに関してはMatiasに同意

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

Microsoft Unity Framework

2

:あなたのコードは次のようになります。取り組もうとしている別の問題は、dbプロバイダ(あなたの例ではMongoDB)に強く依存していることです。あなたのデータアクセスを本当にスワップアウトできるのはインターフェイスの後ろに隠れるほど簡単なことではありませんが、そうするテクニックは依存性注入と呼ばれ、MyClassコードでそのフォーム(コンストラクタインジェクション)を使用しています。それはどこか別の場所へのクラスのうち、ハード依存性の問題をプッシュすることhttp://jamesshore.com/Blog/Dependency-Injection-Demystified.html

あなたが正しいです:

は、ここで依存性注入の概要です。幸いにも、私たちが後で注入して使用したいこれらの依存関係を結びつけて管理するためのツールがあります。これらはInversion of Control Containersとして知られており、コードや設定ファイルの依存関係を指定して解決することができます。ここではそれらについてのSOの質問があります:

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

Autofac、のStructureMap、およびUnityが、私は成功を収めて使用しましたいくつかあります。

希望すると便利です。

関連する問題