【问题标题】:How to Inject EF DbContext in Wpf using caliburn micro如何使用 caliburn micro 在 Wpf 中注入 EF DbContext
【发布时间】:2021-08-30 14:24:56
【问题描述】:

我尝试通过Entity框架之上的Repositories构建WPF应用程序与数据库交互,我使用caliburn micro作为MVVM框架

问题是当我尝试通过Simple Container 在 ViewModels 中注入 Repertories 时,它不会实例化 My DbContext

存储库

public class UserRepo : IUserRepo
{
    private AppDb _ctx;

    public UserRepo(AppDb ctx)
    {
            _ctx = ctx;
    }
}

应用上下文

public class AppDb : DbContext
{
    public AppDb(DbContextOptions options) : base(options)
    {
    }

    public DbSet<User> Users { get; set; }
}

简单容器上的配置

class Bootstrapper : BootstrapperBase
{

    private SimpleContainer _container = new SimpleContainer();
    private AppDb _db;
    public Bootstrapper()
    {
        Initialize();

        var options = new DbContextOptionsBuilder<AppDb>()
                      .UseSqlServer(@"Server=(localdb)\MSSQLLocalDB;Database=XRaySystem;Integrated Security=True;")
                      .Options;

        _db = new AppDb(options);
    }

    protected override void Configure()
    {
        _container.Instance(_container);

        _container
            .Singleton<IWindowManager, WindowManager>()
            .Singleton<IEventAggregator, EventAggregator>();
        //register the DataContext
        // i don't know how to add it
        _container.RegisterInstance(typeof(AppDb), null, _db); // <<<<<<<<<< how to add this correctly 
        //Register Reporisotries
        _container
            .PerRequest<IUserRepo, UserRepo>();
        //Register ViewModels
        GetType().Assembly.GetTypes()
            .Where(type => type.IsClass)
            .Where(type => type.Name.EndsWith("ViewModel"))
            .ToList()
            .ForEach(viewModelType => _container.RegisterPerRequest(
                viewModelType, viewModelType.ToString(), viewModelType));
    }
    protected override void OnStartup(object sender, StartupEventArgs e)
    {


        DisplayRootViewFor<DashBoardViewModel>();
        //base.OnStartup(sender, e);
    }

    protected override object GetInstance(Type service, string key)
    {
        return _container.GetInstance(service, key);
    }

    protected override IEnumerable<object> GetAllInstances(Type service)
    {
        return _container.GetAllInstances(service);
    }


    protected override void BuildUp(object instance)
    {
        _container.BuildUp(instance);
    }
}

查看模型

class DoctorViewModel : Screen
{
    private readonly IUserRepo _userRepo;

    public DoctorViewModel(IUserRepo userRepo)
    {
        _userRepo = userRepo;
    }
}

UserRepo 已实例化,但 AppDb 为空

我的问题

如何配置简单容器将AppDb添加到UserRepo

我转载了同样的problem in on GitHub

【问题讨论】:

  • 你为什么不像以前的电话那样使用_container.Instance(_db);
  • @Nkosi 我之前尝试过...当我使用_container.Instance(_db); 时,同样的问题仍然存在
  • 那么显示的代码应该可以工作,除非提供的示例中省略了更多细节
  • @Nkosi 我在app on github 中重现了同样的问题,请查看

标签: c# wpf entity-framework caliburn.micro


【解决方案1】:

经过一番调试,我发现Configure方法先运行然后构造函数调用!!所以实例化是在配置已经用 null 完成之后发生的

我通过在 Configure 方法本身中添加 _db 的实例化来解决它

class Bootstrapper : BootstrapperBase
{

    private SimpleContainer _container = new SimpleContainer();
    private AppDb _db;
    public Bootstrapper()
    {
        Initialize();
    }

    protected override void Configure()
    {
        var options = new DbContextOptionsBuilder<AppDb>()
                     .UseSqlServer(@"Server=(localdb)\MSSQLLocalDB;Database=XRaySystem;Integrated Security=True;")
                     .Options;

        _db = new AppDb(options); //<<<< solve the problem

        _container.Instance(_container);

        _container
            .Singleton<IWindowManager, WindowManager>()
            .Singleton<IEventAggregator, EventAggregator>();
        //register the DataContext
        _container.Instance(_db);
        // _container.RegisterInstance(typeof(AppDb), null, _db); 
        
         //Register Reporisotries
         _container
            .PerRequest<IUserRepo, UserRepo>();
        //Register ViewModels
        GetType().Assembly.GetTypes()
            .Where(type => type.IsClass)
            .Where(type => type.Name.EndsWith("ViewModel"))
            .ToList()
            .ForEach(viewModelType => _container.RegisterPerRequest(
                viewModelType, viewModelType.ToString(), viewModelType));
    }
    protected override void OnStartup(object sender, StartupEventArgs e)
    {

        DisplayRootViewFor<DashBoardViewModel>();
        //base.OnStartup(sender, e);
    }

    protected override object GetInstance(Type service, string key)
    {
        return _container.GetInstance(service, key);
    }

    protected override IEnumerable<object> GetAllInstances(Type service)
    {
        return _container.GetAllInstances(service);
    }


    protected override void BuildUp(object instance)
    {
        _container.BuildUp(instance);
    }
}

【讨论】:

    猜你喜欢
    • 2013-06-26
    • 2020-05-22
    • 1970-01-01
    • 2019-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-29
    • 1970-01-01
    相关资源
    最近更新 更多