前提・実現したいこと
DrylocにDbContextを設定したいです、ASP.NET Core MVCはデフォルトのコンテナを利用しましたが、
WPFアプリ(.NET 5)の場合はなかったので、Drylocを使用したいですが、ネットで調べてもやり方がわかりませんでした。
C#
1// App.xaml.cs 2 3protected override void RegisterTypes(IContainerRegistry containerRegistry) { 4 // appsettings.jsonから接続文字列を取得 5 IConfiguration configuration = new ConfigurationBuilder() 6 .SetBasePath(Directory.GetCurrentDirectory()) 7 .AddJsonFile(path: "appsettings.json", optional: true, reloadOnChange: true) 8 .Build(); 9 10 string connectionString = configuration.GetConnectionString("DbConnection"); 11 12 // コンテナのインスタンスを取得する(Dryloc) 13 IContainer container = containerRegistry.GetContainer(); 14 15 // TestDbContext ※Drylocの場合のやり方がわからない。 16 // container.Register<TestDbContext>(ifAlreadyRegistered: IfAlreadyRegistered.AppendNotKeyed); 17 18 /* 19 ASP.NET Core MVC(.NET 5)の場合 20 services.AddDbContext<TestDbContext>(options => { 21 options.UseLazyLoadingProxies(); 22 options.UseSqlServer(Configuration.GetConnectionString("DbConnection")) 23 }; 24 */ 25}
C#
1public class TestDbContext : DbContext { 2 public TestDbContext(DbContextOptions<AddDbContext> options) : base(options) { 3 4 } 5}
(追記)
Microsoft.Extensions.DependencyInjectionにてDbContextを使用する場合。
C#
1// Microsoft.Extensions.DependencyInjection の場合 2IConfiguration configuration = new ConfigurationBuilder() 3 .SetBasePath(Directory.GetCurrentDirectory()) 4 .AddJsonFile(path: "appsettings.json", optional: true, reloadOnChange: true) 5 .Build(); 6 7IServiceCollection services = new ServiceCollection(); 8services.AddDbContext<TestDbContext>(options => { 9 options.UseLazyLoadingProxies(); 10 options.UseSqlServer(configuration.GetConnectionString("DbConnection")); 11});
ただし、WPFで使用しているPrismフレームワークがDrylocを使用していて、上記のMicrosoft.Extensions.DependencyInjectionが使えないため、Dryloc(またはUnity)が使えればよいのですが。
どなたかご教授お願いします。
(追記 修正) ※元のコードは間違いのため削除しました。
BluOxyさんの回答を元に実際のコードを記載しました。
C#
1// ITestDbContext 2 3using Microsoft.EntityFrameworkCore; 4using System.Threading; 5using System.Threading.Tasks; 6 7namespace DomainModel { 8 public interface ITestDbContext { 9 // インターフェースのプロパティ・メソッドを使うわけではなさそうなので、 10 // DbContextに追加したメソッドは全て定義しなければいけないのかは不明 11 12 // public Task<int> SaveChangesAsync(CancellationToken cancellationToken = new CancellationToken()); 13 14 // DbSet<Department> Departments { get; set; } 15 } 16}
C#
1// TestDbContext 2 3using Microsoft.EntityFrameworkCore; 4using System; 5using System.Collections.Generic; 6using System.ComponentModel.DataAnnotations; 7using System.Diagnostics; 8using System.Linq; 9using System.Threading; 10using System.Threading.Tasks; 11 12namespace DomainModel { 13 public class TestDbContext : DbContext, ITestDbContext { 14 15 public TestDbContext(DbContextOptions<TestDbContext> options) : base(options) { 16 17 } 18 19 public async override Task<int> SaveChangesAsync(CancellationToken cancellationToken = new CancellationToken()) { 20 // ... 21 } 22 23 /// <summary> 24 /// Override OnModelCreating 25 /// </summary> 26 /// <param name="modelBuilder"></param> 27 protected override void OnModelCreating(ModelBuilder modelBuilder) { 28 // ... 29 30 base.OnModelCreating(modelBuilder); 31 } 32 33 protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { 34 string connectionString = "Data Source=..."; 35 36 optionsBuilder.UseSqlServer(connectionString); 37 optionsBuilder.UseLazyLoadingProxies(); 38 39 base.OnConfiguring(optionsBuilder); 40 } 41 42 // Test用の適当なクラス 43 public DbSet<Department> Departments { get; set; } 44 } 45}
C#
1// App.xaml 2 3using DomainModel; 4using DryIoc; 5using Microsoft.Extensions.Configuration; 6using Prism.DryIoc; 7using Prism.Ioc; 8using System.IO; 9using System.Windows; 10using UserInterface.Views; 11 12namespace UserInterface { 13 /// <summary> 14 /// Interaction logic for App.xaml 15 /// </summary> 16 public partial class App { 17 protected override Window CreateShell() { 18 return Container.Resolve<MainWindow>(); 19 } 20 21 protected override void RegisterTypes(IContainerRegistry containerRegistry) { 22 // appsettings.jsonはDbContextのDomainModelレイヤーに用意して読み込ませるかも 23 // (または依存関係が逆転しない他の方法) 24 // IConfiguration configuration = new ConfigurationBuilder() 25 // .SetBasePath(Directory.GetCurrentDirectory()) 26 // .AddJsonFile(path: "appsettings.json", optional: true, reloadOnChange: true) 27 // .Build(); 28 29 // Drylocを利用する場合 30 var container = containerRegistry.GetContainer(); 31 container.Register<ITestDbContext, TestDbContext>(); 32 } 33 } 34}
appsettings.jsonはDbContextのDomainModelレイヤーに用意して読み込ませることを検討しようと思います。
(または依存関係が逆転しない他の方法)
DbContextインターフェースには、DbContextに追加したメソッドは全て定義しなければいけないのかはまだ不明ですが。
また、下記のPMのコマンドが使えなくなってしまいました。プロジェクト(レイヤー)の指定は間違っていないのですが。
※標準のDI(Microsoft.Extensions.DependencyInjectionの時)に使えていたPMコマンドではありますが。
txt
1PM > Add-Migration init -Context TestDbContext -o "Migrations/TestDb" 2PM > Update-Database -Context TestDbContext
エラー内容
txt
1Build started... 2Build succeeded. 3Unable to create an object of type 'TestDbContext'. For the different patterns supported at design time, see https://go.microsoft.com/fwlink/?linkid=851728
(追記)PMコマンドでエラーしたので、デフォルトの引数無しコンストラクタを追加して対処しました。
PMコマンドが実行できるようになりました。
C#
1// TestDbContext 2 3using Microsoft.EntityFrameworkCore; 4using System; 5using System.Collections.Generic; 6using System.ComponentModel.DataAnnotations; 7using System.Diagnostics; 8using System.Linq; 9using System.Threading; 10using System.Threading.Tasks; 11 12namespace DomainModel { 13 public class TestDbContext : DbContext, ITestDbContext { 14 15 public TestDbContext() { 16 17 } 18 19 public TestDbContext(DbContextOptions<TestDbContext> options) : base(options) { 20 21 } 22 23 public async override Task<int> SaveChangesAsync(CancellationToken cancellationToken = new CancellationToken()) { 24 // ... 25 } 26 27 /// <summary> 28 /// Override OnModelCreating 29 /// </summary> 30 /// <param name="modelBuilder"></param> 31 protected override void OnModelCreating(ModelBuilder modelBuilder) { 32 // ... 33 34 base.OnModelCreating(modelBuilder); 35 } 36 37 protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { 38 string connectionString = "Data Source=..."; 39 40 optionsBuilder.UseSqlServer(connectionString); 41 optionsBuilder.UseLazyLoadingProxies(); 42 43 base.OnConfiguring(optionsBuilder); 44 } 45 46 public DbSet<Department> Departments { get; set; } 47 } 48}
回答3件
あなたの回答
tips
プレビュー