簡體   English   中英

如何將.net核心EF注入WPF應用程序

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

我想將.NET Core EntityFramework DbContext (位於.net標准庫中)注入WPF應用程序。

我嘗試了這種Unity方法

啟動時

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<MainWindow>()處收到此錯誤:

當前類型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

最初的錯誤是因為容器選擇了預期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();
    }
}

在任何可能的情況下,通過構造函數注入的顯式依賴關系原則應優先於屬性注入。

但是由於大多數視圖都不適用於構造函數注入,因此通常會應用后者。 通過在將視圖模型注入視圖之前確保視圖模型具有所有必要的依賴關系,可以確保在需要時所有必需的值都可用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM