こんにちは私はアプリケーション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
に渡す必要がありますか?
SimpleInjectorに、タイプUsersDbContext
のコンストラクターを持っているように見えるDbContextOptions
をインスタンス化する方法を指示する必要があります。
以下のようにデリゲート(ファクトリ)パラメータを受け取るDbContext
メソッドのオーバーロードを使用して、Register
の登録方法を変更します。
container.Register<DbContext>(() => {
var options = // Configure your DbContextOptions here
return new UsersDbContext(options);
});
すべての答えが私にはうまくいきませんが、私は別のアプローチを見つけました。
container.CrossWire<IntellisenseDbContext>(app);
できます
これは私が尋ねたものに対する答えではありませんが、私が最終的に使用した代替手段です。多分これは将来他の人に役立つかもしれません
デフォルトのDIコンテナからDbContextをクロスワイヤリングしました。
container.Register(app.ApplicationServices.GetService<UsersDbContext>, Lifestyle.Singleton);
DI構成を確認した後、DbContextは1つの場所にしか登録されていないため、これがより良い解決策であると感じました。 Entity FrameworkとIdentityを使用しているので、そのままにしておくことができました。これらは両方とも、フレームワークの依存関係を登録するために保持しているデフォルトのDIコンテナーに登録されており、DbContextにアクセスする必要があります。
コンストラクターを作成し、オプションオブジェクトを依存関係として渡します。 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);
}
}