0

さまざまな実装をサポートするはずの汎用データ アクセス レイヤーがあるとします。これを実現するためIPeristenceServiceに、永続層内のデータにアクセスするためのすべてのメソッドを定義する基本インターフェースがあります。インターフェイスは次のようになります。

public interface IPersistence
{
    TData GetData<TData, TKey>(TKey Key);
}

したがって、永続化サービスは、インターフェースによってのみ定義されるオブジェクトのインスタンスを作成することはできません。そのため、メソッドの実装を制限することは適切な決定GetDataです。

public interface IPersistence
{
    TData GetData<TData, TKey>(TKey Key) where TData : class, new();
}

このインターフェイスを実装している開発者は、インターフェイス ポインターを返そうとするとコードをコンパイルできないため、これは非常に簡単です。永続化レイヤー内のデータは、インターフェイスではなく、実装されたオブジェクトで表す必要があります!

ここで、エンティティによって表されるリレーショナル データベース内のデータを永続化する永続化サービスを作成しているとします。すべてのエンティティは、1 つの基本インターフェイスから継承しています: IEntity. 永続化サービスはエンティティのみを永続化できるため、非エンティティ オブジェクトの受け渡しは失敗する必要があります。したがって、渡されたオブジェクト インスタンスが から継承されているかどうかを検証する必要がありますIEntity。where 表記を使用すると、コンパイル時にこれが可能になりますが、次のようなインターフェイスを実装するだけです。

public class DbPersistence : IPersistence
{
    public TData IPersistence.GetData<TData, TKey>(TKey Key)
        where TData : IEntity, class, new();
    {
        // fancy data access code
    }
}

動作しませんよね?

私がやろうとしていることを理解する方法はありますか?

前もって感謝します :-)

4

1 に答える 1

4

の型制約TDataは、実装しているインターフェイスメソッドから継承されます。そのため、実装でそれらを変更することはできません。私が考えることができる2つの典型的な解決策があります:

IEntity制約をインターフェース定義まで移動します

public interface IPersistence
{
    TData GetData<TData, TKey>(TKey Key) where TData : class, IEntity, new();
}

これは多くの場合に適切です。なぜなら、すべての永続化されたオブジェクト間の一定量の共通の基盤が合理的であり、望ましいからです。

元のインターフェイスを明示的に実装し、専用のインターフェイスを公開します

public interface IPersistence
{
    TData GetData<TData, TKey>(TKey Key) where TData : class, new();
}

public interface IDbPersistence
{
    TData GetData<TData, TKey>(TKey Key) where TData : class, IEntity, new();
}

public class DbPersistence : IPersistence, IDbPersistence
{
    TData IPersistence.GetData<TData, TKey>(TKey Key)
    {
        // fancy data access code
    }

    TData GetData<TData, TKey>(TKey Key)
    {
        return ((IPersistence)this).GetData<TData, TKey>(Key);
    }
}

このようにして、カスタム永続層をより豊富に指定されたものとして使用できるIDbPersistenceと同時に、についてしか知らないデータアクセス層の部分との互換性を維持できますIPersistence

于 2012-07-10T10:03:05.887 に答える