【问题标题】:How to inject .net core EF into WPF application如何将 .net core EF 注入 WPF 应用程序
【发布时间】:2018-11-24 23:55:50
【问题描述】:

我想将我的 .NET Core EntityFramework DbContext(位于 .net 标准库中)注入到我的 WPF 应用程序中。

我试过this Unity approach

开机启动

var container = new UnityContainer();
container.RegisterType<ApplicationDbContext>();
var mainWindow = container.Resolve<MainWindow>();

base.OnStartup(e);

主窗口

private ApplicationDbContext _db;
[Dependency]
public ApplicationDbContext Db
{
    get
    {
        return _db;
    }
    set
    {
        _db = value;
    }
}

public MainWindow()
{
    //StandardDatabase.Commands.Test();

    InitializeComponent();
    DataContext = this;
    FrameContent.Navigate(new PageConsignments());
}

但我在container.Resolve&lt;MainWindow&gt;() 收到此错误:

当前类型 System.Collections.Generic.IReadOnlyDictionary`2[System.Type,Microsoft.EntityFrameworkCore.Infrastructure.IDbContextOptionsExtension] 是接口,无法构造。您是否缺少类型映射?

有谁知道我做错了什么?欢迎任何关于更好的方法的建议

ApplicationDbContext

public ApplicationDbContext() : base() { }

public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
    : base(options)
{ }

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    optionsBuilder
        .UseLazyLoadingProxies()
        .UseSqlServer("Server=L-TO-THE-APTOP\\SQLEXPRESS;Database=Maloli;Trusted_Connection=True;MultipleActiveResultSets=true");

    optionsBuilder.ConfigureWarnings(x => x.Ignore(CoreEventId.LazyLoadOnDisposedContextWarning));
}

根据 Nkosi 的建议,我从上下文中删除了 ApplicationDbContext(options) ctor,这样就消除了错误。但是我现在在 MainWindow 中检查 Db 的值:

private ICommand goPack;
public ICommand GoPack
{
    get
    {
        return goPack
            ?? (goPack = new ActionCommand(() =>
            {
                var c = _db.Parts;
                FrameContent.Navigate(new PageConsignments());
            }));
    }
}

但它返回null

【问题讨论】:

  • 您是否正确配置了ApplicationDbContext 与容器。您似乎没有为 DbContext 设置上下文构建器选项
  • 删除带有选项的构造函数
  • @Nkosi 这似乎已经摆脱了错误!但是,在MainWindow 中,我可以看到Dbnull
  • @Bassie 取决于您何时检查其值。如果你在容器有机会注入依赖之前检查它,比如在构造函数中有一个断点,那么在初始化过程中它肯定会为空

标签: c# wpf entity-framework-core .net-standard


【解决方案1】:

最初的错误是因为容器选择了预期 DbContextOptionsBuilder 的构造函数,conateinr 不知道如何正确解决。

由于上下文是在 OnConfiguring 覆盖中配置的,因此不需要

public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
    : base(options)
{ }

删除该构造函数,以便容器解析上下文而不会出错。

根据依赖项初始化的流程和对其的访问,该上下文应该真正显式地注入到视图模型中,而不是直接注入到视图中。

遵循 MVVM,在视图模型中拥有所有必要的依赖项和可绑定属性

public class MainWindowViewModel : BaseViewModel {
    private readonly ApplicationDbContext db;

    public MainWindowViewModel(ApplicationDbContext db) {
        this.db = db;            
    }

    private ICommand goPack;
    public ICommand GoPack {
        get {
            return goPack
                ?? (goPack = new ActionCommand(() =>
                {
                    var c = db.Parts;
                    FrameContent.Navigate(new PageConsignments());
                }));
        }
    }
}

更新视图以依赖视图模型

public class MainWindow : Window {
    [Dependency]
    public MainWindowViewModel ViewModel {
        set { DataContext = value; }
    }

    public MainWindow() {
        InitializeComponent();
        Loaded += OnLoaded;
    }

    void OnLoaded(object sender, EventArgs args) {
        FrameContent.Navigate(new PageConsignments());
    }
}

现在剩下的就是确保所有依赖项都注册到容器中

public class App : Application {
    protected override void OnStartup(StartupEventArgs e) {
        IUnityContainer container = new UnityContainer();
        container.RegisterType<ApplicationDbContext>();
        container.RegisterType<MainWindowViewModel>();
        container.RegisterType<MainWindow>();

        MainWindow mainWindow = container.Resolve<MainWindow>();
        mainWindow.Show();
    }
}

在可能的情况下,The Explicit Dependencies Principle 通过构造函数注入应该优先于属性注入。

但由于大多数视图不适合构造函数注入,因此通常应用后者。通过在将视图模型注入视图之前确保视图模型具有所有必要的依赖关系,您可以确保所有必需的值在需要时可用。

【讨论】:

  • 这适用于MainWindow,但是当尝试在该窗口中显示其他页面时,它们没有所需的依赖项
  • 这只是设计选择的问题。您可以轻松地注入必要的页面并将它们向前传递。
  • @Nkosi 使用这种方法,我是否需要明确地Dispose DbContext
猜你喜欢
  • 2021-08-26
  • 2020-11-07
  • 2020-04-09
  • 2023-01-24
  • 1970-01-01
  • 2017-12-03
  • 2019-06-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多