1

汎用リポジトリクラスがあります。

public class Repository<TEntity> where TEntity : class
{
    public virtual TEntity Create()
    {
        // Create implementation.
    }
    public virtual bool Add(TEntity entity)
    {
        // Add implementation.
    }
    public virtual bool Delete(TEntity entity)
    {
        // Delete implementation.
    }
    public virtual int SaveChanges()
    {
        // Save changes implementation.
    }
}

主にメソッドの動作と完全に一致しないタイプがいくつかあるCreateので、特定の実装を作成したいと思います。

何かのようなもの:

public class SpecificEntityRepository : Repository<SpecificEntity>
{
    public override SpecificEntity Create()
    {
        // Other create implementation.
    }
}

Repository<SpecificEntity>人がのメソッドの値を返すために使用する場合、SpecificEntityRepositoryたとえば、引数の型が等しい場合SpecificEntityRepositoryのコンストラクターに戻る方法はありますか?Repository<>SpecificEntity

私はこれを行うための一般的な方法を探しています。私のプロジェクトの最終バージョンには、最大200の特定のリポジトリが存在する可能性があり、機能の95%が汎用です。

4

2 に答える 2

1

人々が作成するのを防ぎたい場合はRepository<SpecificEntity>Repositoryコンストラクターprotectedを作成し、ファクトリメソッドを介してのみインスタンスの作成を許可できます。

例えば:

public class Repository<TEntity> where TEntity : class
{
    private static readonly Dictionary<Type, Func<object>> specificRepositories =
        new Dictionary<Type, Func<object>>
        {
            { typeof(SpecificEntity), () => new SpecificRepository() }
        };

    protected Repository() {}

    public static Repository<T> Create<T>() where T : class
    {
        var entityType = typeof(T);
        if (specificRepositories.ContainsKey(entityType)) {
            return (Repository<T>)specificRepositories[entityType]();
        }
        else {
            return new Repository<T>();
        }
    }

    // default implementations omitted
}

エンティティタイプに基づくリポジトリインスタンスの解決は、Dictionary保守がより便利であるために基づいていますが、特定のリポジトリタイプのいくつかについて話している場合は、代わりにif/を使用できます。else if

于 2013-02-28T11:25:38.953 に答える
1

特定のコンストラクターを呼び出した後は、オブジェクトのクラスを変更することはできません。
ただし、実際のコンストラクターを直接呼び出す代わりに、ファクトリメソッドを使用することもできます。

public static Repository<T> CreateRepository<T>() {
    if (typeof(T) == typeof(SpecificEntity)) {
        return new SpecificEntityRepository();
    }
    return new Repository<T>();
}

確実に使用するには、実際のコンストラクターを保護する必要があります。

于 2013-02-28T11:25:45.623 に答える