web-dev-qa-db-ja.com

SimpleInjectorと.NetCoreにDBコンテキストを登録する

こんにちは私はアプリケーションDIにSimpleInjectorを使用しています。フレームワークDIのデフォルトDIを維持しました。

しかし、私はDbContextをSimpleInjectorに登録する必要があります。アプリケーションを実行すると

_container.Verify()
_

次のエラーが発生します

ActivationException:タイプUsersDbContextのコンストラクターには、登録されていない名前 'options'およびタイプDbContextOptionsのパラメーターが含まれています。 DbContextOptionsが登録されていることを確認するか、UsersDbContextのコンストラクターを変更してください。

関数SimpleInjectorConfig.InitializeContainer(app, _container)のSimpleInjectoreにDbContextを登録しています

_// DbContext
container.Register<DbContext, UsersDbContext>();
_

そして私のスタートアップは

_public void ConfigureServices(IServiceCollection services)
{
    var conString = Configuration.GetConnectionString("DefaultConnection");

    // Add framework services.
    services.AddDbContext<UsersDbContext>(options => options.UseSqlServer(conString));

    services.AddIdentity<User, IdentityRole>()
            .AddEntityFrameworkStores<UsersDbContext>()
            .AddDefaultTokenProviders();

    IdentityConfigurationService.ConfigureIdentityOptions(services);

    services.AddMvc();

    // Add application services
    services.AddSingleton<IControllerActivator>(new SimpleInjectorControllerActivator(_container));
    services.AddSingleton<IViewComponentActivator>(new SimpleInjectorViewComponentActivator(_container));

    services.UseSimpleInjectorAspNetRequestScoping(_container);
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    SimpleInjectorConfig.InitializeContainer(app, _container);

    loggerFactory.AddConsole(Configuration.GetSection("Logging"));
    loggerFactory.AddDebug();

    _container.Verify();

    app.UseMvc();
}
_

オプションに問題があることはわかっていますが、SimpleInjectorがコンテナに登録されているデフォルトの接続文字列をどのように必要としているかわかりません。これはSimpleInjectorに渡すことができるものですか?または、DbContextFactoryを使用して接続文字列をUserDbContextに渡す必要がありますか?

7
Jeff Finn

SimpleInjectorに、タイプUsersDbContextのコンストラクターを持っているように見えるDbContextOptionsをインスタンス化する方法を指示する必要があります。

以下のようにデリゲート(ファクトリ)パラメータを受け取るDbContextメソッドのオーバーロードを使用して、Registerの登録方法を変更します。

container.Register<DbContext>(() => {
    var options = // Configure your DbContextOptions here
    return new UsersDbContext(options);
});
13
CodeNotFound

すべての答えが私にはうまくいきませんが、私は別のアプローチを見つけました。

container.CrossWire<IntellisenseDbContext>(app);

できます

1
Alados

これは私が尋ねたものに対する答えではありませんが、私が最終的に使用した代替手段です。多分これは将来他の人に役立つかもしれません

デフォルトのDIコンテナからDbContextをクロスワイヤリングしました。

container.Register(app.ApplicationServices.GetService<UsersDbContext>, Lifestyle.Singleton);

DI構成を確認した後、DbContextは1つの場所にしか登録されていないため、これがより良い解決策であると感じました。 Entity FrameworkとIdentityを使用しているので、そのままにしておくことができました。これらは両方とも、フレームワークの依存関係を登録するために保持しているデフォルトのDIコンテナーに登録されており、DbContextにアクセスする必要があります。

0
Jeff Finn

コンストラクターを作成し、オプションオブジェクトを依存関係として渡します。 DIにもオプションを登録します。接続文字列はOnConfiguringメソッドで設定できます。

public partial class FooContext : DbContext
{
    private FooContextOptions _options;

    public FooContext(FooContextOptions options)
    {
        _options = options;
    }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseNpgsql(_options.ConnectionString);
    }
}
0
Ilya Chumakov