10

Entity Frameworkのリポジトリ ソリューションを実装しようとしていますが、Unity を使用してジェネリックを含む型を登録するのに問題があります。

与えられた:

    // IRepository interface
    public interface IRepository<TEntity>
    {
        // omitted for brevity
    }

    // Repository implementation
    public class Repository<TEntity, TContext> : IRepository<TEntity>, IDisposable 
            where TEntity : class
            where TContext : DbContext
    {
        // omitted for brevity
    }

    // service layer constructor
    public MyServiceConstructor(IRepository<Account> repository)
    {
        _repository = repository;
    }

IRepository から Repository へのタイプ マッピングを登録する必要があります。しかし、この種のマッピングの Unity 構文に問題があります。

私は運がないので次のことを試しました:

container.RegisterType<IRepository<>, typeof(Repository<,>)>();
container.RegisterType<typeof(IRepository<>), Repository<,>>();

編集

@Steven の応答に基づいて、現在次の実装があります。

// UnityRepository implementation   
public class UnityRepository<TEntity> : Repository<TEntity, MyDbContextEntities>
        where TEntity : class
{
    public UnityRepository() : base(new MyDbContextEntities()) { }
}

// Unity bootstrapper
container.RegisterType(typeof(IRepository<>), typeof(UnityRepository<>));
4

1 に答える 1

17

あなたは次のことをしようとしています:

container.RegisterType(typeof(IRepository<>), typeof(Repository<,>));

これは通常は機能しますが、この場合はうまくいきません。なぜなら、 にはIRepository<TEntity>1 つのジェネリック引数Repository<TEntity, TContext>があり、2 つのジェネリック引数があり、Unity は (明らかに) にどのタイプを入力する必要があるかを推測できないからですTContext

必要なものはこれです:

container.RegisterType(
    typeof(IRepository<>),
    typeof(Repository<, MyDbContextEntities>));

つまり、Repository<TEntity, TContext>部分的に開いたジェネリック型 (1 つのパラメーターが入力された) として を提供する必要があります。残念ながら、C# コンパイラはこれをサポートしていません。

しかし、C# がこれをサポートしていたとしても、Unity はパーシャル オープン ジェネリック型をサポートしていません。実際、ほとんどの IoC ライブラリ eworks はこれをサポートしていません。そして、それをサポートするその1 つのライブラリについては、部分的なオープン ジェネリック型を作成するために、次の (厄介なこと) を行う必要があります。

Type myDbContextEntitiesRepositoryType =
    typeof(Repository<,>).MakeGenericType(
        typeof(Repository<,>).GetGenericParameters().First(),
        typeof(MyDbContextEntities));

ただし、これを機能させるための簡単な回避策があります。1 つのジェネリック型で派生クラスを定義します

// Special implementation inside your Composition Root
public class UnityRepository<TEntity> : Repository<TEntity, MyDbContextEntities>
        where TEntity : class
{
    public UnityRepository([dependencies]) : base([dependencies]) { }
}

これで、このオープン ジェネリック型を簡単に登録できます。

container.RegisterType(typeof(IRepository<>), typeof(UnityRepository<>));
于 2013-09-18T19:33:06.200 に答える