代码之家  ›  专栏  ›  技术社区  ›  Bassie

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

  •  1
  • Bassie  · 技术社区  · 7 年前

    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<MainWindow>() :

    有人知道我做错了什么吗?欢迎就更好的方法提出任何建议

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

    根据恩科西的建议,我删除了 ApplicationDbContext(options) 从上下文中删除ctor,这样就消除了错误 Db 在这里 MainWindow :

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

    但它又回来了 null

    1 回复  |  直到 7 年前
        1
  •  5
  •   Nkosi    7 年前

    最初的错误是因为容器正在选择预期的构造函数 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

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