5

Simple Injector Dependency Injection フレームワークの速度に感銘を受けたため、それに切り替えようとしています。

 private static void RegisterServices(Container container)
 {
     container.RegisterPerWebRequest<IDbContext, DbContext1>();
     ////container.RegisterPerWebRequest<IDbContext, DbContext2>();    
     container.RegisterPerWebRequest<IUnitOfWork, UnitOfWork>();
     container.RegisterPerWebRequest<IColourRepository, ColourRepository>();

ここで、DbContext1 と DbContext2 は BaseDbContext クラスから継承します

public class BaseDbContext<TContext> : DbContext, IDbContext where TContext : DbContext

かなり単純な IDbContext インターフェイスを実装します (SO で提供される多くのものと同様)。

public interface IDbContext
{
    IQueryable<TEntity> Find<TEntity>() where TEntity : class;
    DbSet<TEntity> Set<TEntity>() where TEntity : class;
    int SaveChanges();
    void Dispose();
}

DbContext クラスを 1 つだけ使用すると、正常に動作します。リポジトリが挿入されたり、データがプルされたりします。

ただし、コードファーストの DbContext には数百のクラスが含まれるため、それぞれに少数の DbSet を含む境界付けられたコンテキストを使用したいと思います ( Shrink EF Models with DDD Bounded Contexts )。

private static void RegisterServices(Container container)
 {
     container.RegisterPerWebRequest<IDbContext, DbContext1>();
     container.RegisterPerWebRequest<IDbContext, DbContext2>();

     container.RegisterPerWebRequest<IUnitOfWork, UnitOfWork>();
     container.RegisterPerWebRequest<IColourRepository, ColourRepository>();

次に、例外が発生します。

System.InvalidOperationException がユーザー コードによって処理されませんでした。現在の登録を上書きできるようにするには、Container.Options.AllowOverridingRegistrations を true に設定してください。Source=SimpleInjector StackTrace: at SimpleInjector.Container.ThrowWhenTypeAlreadyRegistered(Type 型) at SimpleInjector.Container.AddRegistration(Type serviceType, 登録登録) at SimpleInjector.Container.Register[TService,TImplementation](ライフスタイル, String serviceTypeParamName, String implementationTypeParamName) at SimpleInjector.Container.Register[TService,TImplementation](ライフスタイル・ライフスタイル) を SimpleInjector に登録します。

私が提案に従えば:

container.Options.AllowOverridingRegistrations = true;

次に、DbContext2 が DbContext1 をオーバーライドしているように見えます。たとえば、DbSet "Colour" は DbContext1 にあり、アクセスできなくなりました。

Additional information: The entity type Colour is not part of the model for the current context.

Simple Injector とバインドされた DbContext を一緒に使用するにはどうすればよいですか?

[アップデート]

DbContexts はコントローラで直接使用されるのではなく、Simple Injector がコンストラクタで初期化できるリポジトリの依存関係です。

 public class ColoursController : ApiController
{
    private readonly IColourRepository _repository;
    private readonly ModelFactory _modelFactory;

    public ColoursController(IColourRepository repository)
    {
        _repository = repository;
        _modelFactory = new ModelFactory();
    }

どこ

 public class ColourRepository : Repository<Colour>, IColourRepository
{
    public ColourRepository(IDbContext context) : base(context) { }

ColourRepository は DbContext1 の具体的な実装を想定していますが、他のリポジトリでは DbContext2 が必要になる場合があります (エンティティのセットが異なります)。

DbContext1 と DbContext2 の両方に IDbContext インターフェイス (または基本型) を使用できない理由がわかりません。

Unity でできること:

container.RegisterType<IDbContext, NorthwindContext>(new PerRequestLifetimeManager(), "NorthwindContext");
container.RegisterType<IDbContext, NorthwindCustomerContext>(new PerRequestLifetimeManager(), "NorthwindCustomerContext");

ニンジェクトはそれを行うことができます。

Simple Injector は CompositeLogger について言及しています。

https://simpleinjector.org/

4

1 に答える 1

6

ColourRepository は DbContext1 の具体的な実装を想定していますが、他のリポジトリでは DbContext2 が必要になる場合があります (エンティティのセットが異なります)。

あなたのデザインは現在あいまいです。あなたのデザインは について話し、IDbContext2 つの実装を持つ 1 つの抽象化しかないように見えますが、それらの実装は交換可能ではありません (リスコフ置換原則違反)。これは、実際には 2 つの異なるインターフェイスが必要であることを示しています。さらに、単一のインターフェースを使用すると、DI 構成がより複雑になり、保守が難しくなります (これは、選択したフレームワークに依存しません)。

したがって、解決策は、各コンテキストに独自のインターフェイスを与えることで、設計からあいまいさを取り除くことです。これにより、リポジトリは必要な抽象化に依存することができます。

public class ColourRepository : Repository<Colour>, IColourRepository
{
    public ColourRepository(ICustomerDbContext context) : base(context) { }
}

これにより、登録を簡素化できます。

container.Register<IDbContext, NorthwindContext>(Lifestyle.Scoped);
container.Register<ICustomerDbContext, NorthwindCustomerContext>(Lifestyle.Scoped);

キー付き登録を使用しても、コアの問題は解決されないことに注意してください。どのキー付きバージョンをどのリポジトリに挿入する必要があるかを明示的に述べる必要が依然としてあります。これにより、DI 構成がメンテナンスの悪夢となり、エラーが発生しやすくなります。

于 2013-11-08T10:47:53.087 に答える