简体   繁体   English

如何将.net核心EF注入WPF应用程序

[英]How to inject .net core EF into WPF application

I would like to inject my .NET Core EntityFramework DbContext (sitting in a .net standard library) into my WPF app. 我想将.NET Core EntityFramework DbContext (位于.net标准库中)注入WPF应用程序。

I tried this Unity approach : 我尝试了这种Unity方法

OnStartup 启动时

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

base.OnStartup(e);

MainWindow 主窗口

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());
}

But I get this error at container.Resolve<MainWindow>() : 但是我在container.Resolve<MainWindow>()处收到此错误:

The current type, System.Collections.Generic.IReadOnlyDictionary`2[System.Type,Microsoft.EntityFrameworkCore.Infrastructure.IDbContextOptionsExtension], is an interface and cannot be constructed. 当前类型System.Collections.Generic.IReadOnlyDictionary`2 [System.Type,Microsoft.EntityFrameworkCore.Infrastructure.IDbContextOptionsExtension]是一个接口,无法构造。 Are you missing a type mapping? 您是否缺少类型映射?

Does anyone know if I'm doing something wrong? 有人知道我做错了吗? Any suggestions on a better way of doing this are welcome 欢迎提出任何更好的方法建议

ApplicationDbContext 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));
}

As per Nkosi's suggestion, I removed the ApplicationDbContext(options) ctor from the context, and that got rid of the error.However I am now checking the value of Db here in MainWindow : 根据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());
            }));
    }
}

But it returns null 但它返回null

The original error was because the container was selecting the constructor that expected DbContextOptionsBuilder which the conateinr did not know how to resolve properly. 最初的错误是因为容器选择了预期DbContextOptionsBuilder的构造函数,而conateinr不知道该如何正确解决。

Since the context is being configured within the OnConfiguring override then there is no need for 由于上下文是在OnConfiguring覆盖范围内配置的,因此不需要

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

Remove that constructor so the container resolve the context without errors. 删除该构造函数,以便容器解析上下文而不会出现错误。

Depending on the flow of dependency initialization and access to it, that context should really be explicitly injected into a view model and not directly on the View. 根据依赖关系初始化和访问的流程,该上下文确实应该显式注入视图模型中,而不是直接在视图上。

Following MVVM, have all the necessary dependencies and bindable properties in the view model 跟随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());
                }));
        }
    }
}

Update the View to depend on the view model 更新视图以取决于视图模型

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());
    }
}

All that is left now is to make sure all dependencies are registered with container 现在剩下的就是确保所有依赖项都已在容器中注册

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();
    }
}

Where ever possible, The Explicit Dependencies Principle via constructor injection should be preferred over property injection. 在任何可能的情况下,通过构造函数注入的显式依赖关系原则应优先于属性注入。

But since most views do not lend well to constructor injection the latter is usually applied. 但是由于大多数视图都不适用于构造函数注入,因此通常会应用后者。 By making sure the view model has all the necessary dependencies before injecting it into the view you ensure that all required values are available when needed. 通过在将视图模型注入视图之前确保视图模型具有所有必要的依赖关系,可以确保在需要时所有必需的值都可用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在 EF 脚手架的 .NET 核心控制台应用程序中管理用户机密? - How to manage user secrets in .NET Core Console Application for EF Scaffolding? 如何使用 caliburn micro 在 Wpf 中注入 EF DbContext - How to Inject EF DbContext in Wpf using caliburn micro 如何在 WPF .NET 核心应用程序中启用控制台? - How do I enable the console in a WPF .NET Core application? 在ASP.NET核心应用程序中将其与EF核心一起使用时,如何加密postgres数据库的几列? - How encrypt few columns of postgres database while using it with EF core in an ASP.NET core application? 如何使用 EF Core 3.1.5 解决 ASP.net Core 应用程序中的 null 引用异常? - How can I resolve null reference exception in ASP.net Core application using EF Core 3.1.5? 如何将 IServiceScope 注入 .NET 核心中的 class - How to inject an IServiceScope into a class in .NET Core 如何在 asp.net 内核 6 中注入 IConfiguration - How to inject IConfiguration in asp.net core 6 如何将范围服务注入DbContext? 网络核心 - How to inject a scoped service into DbContext? Net Core .NET Core 3.1 登录 WPF 应用程序 - .NET Core 3.1 Logging in a WPF application 更改 .net 核心 WPF 应用程序中的网格标签 - Change labels of grid in .net core WPF application
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM