Как внедрить .net core EF в приложение WPF - PullRequest
0 голосов
/ 24 ноября 2018

Я хотел бы добавить мою .NET Core EntityFramework DbContext (в стандартной библиотеке .net) в мое приложение WPF.

Я пытался этот подход 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());
}

Но я получаю эту ошибку на 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 я удалил ctor ApplicationDbContext(options) из контекста, иЭто избавило от ошибки. Однако теперь я проверяю значение Db здесь, в MainWindow:

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

Но возвращается null

1 Ответ

0 голосов
/ 24 ноября 2018

Первоначальной ошибкой было то, что контейнер выбирал конструктор, который ожидал 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();
    }
}

Там, где это возможно, Принцип явных зависимостей через внедрение конструктора должен быть более предпочтительным, чем внедрение свойства.

Но поскольку большинство представлений плохо поддаются внедрению конструктора, обычно применяется последнее.Убедившись, что модель представления имеет все необходимые зависимости, прежде чем вводить ее в представление, вы обеспечите доступность всех необходимых значений при необходимости.

...