3

現在、私は.NETアプリケーション用のDALを設計しようとしているという問題に直面しています。このアプリケーションは、後で何らかのNoSQLデータベースを使用します。
私が今までに評価したNoSQLデータベースは、主キーとして使用するタイプが異なる場合があります。たとえば、MongoDBはプロプライエタリObjectIDを使用しますが、RavenDBは共通のを使用しstringます。だから私の質問は、さまざまなタイプのドメインモデルIDを処理できるようなDALをどのように設計するかということです。

私の最初のアプローチは、ジェネリックドメインモデルを作成することでした。これは次のようになりました。

// Domain Model
public class Filter<TId> {
  public TId Id { get; set; }
  // ...
}

// DAO-interface
public interface IFilterDao<TId> {
  bool Persist(Filter<TId>);
  // ...
}

// This is where the problems begin
public static class DAOFactory {
  public static IFilterDAO<T> GetFilterDAO<T>() {
    // Implementation of IFilterDAO<T> can't be instantiated because types must be known at compile time
  }
}

TDAO-Factoryメソッドのコメントは、すでに問題を説明しています。対応するコードがコンパイル時に生成されるため、実行時に定義できません。

私の2番目と3番目のアプローチは、をまたはのIdいずれかに定義することobjectでしたdynamic。RavenDBはobject文字列が必要なため、を使用できませんでした。を使用dynamicすると、ラムダをRavenDB APIに渡すことができませんでした(コンパイラエラー「式ツリーに動的操作が含まれていない可能性があります」が発生しました)。また、ラムダを使用する代わりに式ツリーを構築することは、時間がかかるため、実際には最後の方法です。

だから私は完全に立ち往生していて、誰かが私を助けてくれることを願っています。前もって感謝します。

更新:私はついにRavenDBをobject使用できるようになりましたが、を使用するのは満足のいくソリューションではありませんobject

4

1 に答える 1

2

コンパイル時に型を知っていれば、静的クラスの問題を解決できますよね?つまり、必然的に、基盤となるデータベースごとに1つのDaoFactory実装が必要になります。

答えは、ファクトリパターンを使用するべきではないということです。代わりに、抽象ファクトリパターンを使用する必要があります。

public class Filter<TId> { 
  public TId Id { get; set; } 
} 

public interface IFilterDao<TId> { 
  bool Persist(Filter<TId>); 
} 

// Note: Can't be static since polymorphism requires an instance!
public abstract class DaoFactory<TId> {
  public abstract IFilterDao<TId> GetFilterDao<TId>();
}

public sealed class MongoDBDaoFactory : DaoFactory<ObjectID> {
  public override IFilterDao<ObjectID> GetFilterDao<ObjectID>() { /* ... */ }
}

public sealed class RavenDBDaoFactory : DaoFactory<String> {
  public override IFilterDao<String> GetFilterDao<String>() { /* ... */ }
}

同様のことをしなければならず、実行時に使用する適切な実装を選択するために依存性注入パターンを使用しようとしましたが、ジェネリックスの問題のため、実際にはそれを行うのは非常に困難です。 抽象ファクトリはここに行くための最良の方法です。

于 2012-06-06T05:21:23.167 に答える