Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 纯DI w/MVVM+;WPF_C#_Wpf_Mvvm_Dependency Injection - Fatal编程技术网

C# 纯DI w/MVVM+;WPF

C# 纯DI w/MVVM+;WPF,c#,wpf,mvvm,dependency-injection,C#,Wpf,Mvvm,Dependency Injection,在MVVM之后尝试使用WPF的纯DI(即没有框架)非常困难。我有马克·希曼的书;然而,他的解决方案似乎与我提出的非常相似: public partial class App : Application { protected override void OnStartup(StartupEventArgs e) { base.OnStartup(e); string connectionString = @"Server=(locald

在MVVM之后尝试使用WPF的纯DI(即没有框架)非常困难。我有马克·希曼的书;然而,他的解决方案似乎与我提出的非常相似:

public partial class App : Application
{
    protected override void OnStartup(StartupEventArgs e)
    {
        base.OnStartup(e);

        string connectionString = @"Server=(localdb)\MSSQLLocalDB;Database=RouteMiningDB;Trusted_Connection=True;";
        RouteMiningDAL.RouteMiningDataContext db = new RouteMiningDAL.RouteMiningDataContext(new DbContextOptionsBuilder().UseSqlServer(connectionString).Options);
        IZIPCodeInfoRepository zipCodeRepo = new RouteMiningDAL.SQLZIPCodeInfoRepository(db);
        ZIPCodeInfoService zipCodeInfoService = new ZIPCodeInfoService(zipCodeRepo);

        ZIPCodeInfoViewModel zipCodeInfoViewModel = new ZIPCodeInfoViewModel(zipCodeInfoService);
        ZIPCodeInfoView zipCodeInfoView = new ZIPCodeInfoView(zipCodeInfoViewModel);

        MainWindow mainWindow = new MainWindow();
        mainWindow.Content = zipCodeInfoView;
        mainWindow.Show();
    }
}
根据其他参考资料以及Mark的书,OnStartup被用作合成根。一切似乎都很好,然而,我觉得我能做的非常有限。例如,我已将
ZIPCodeInfoView
设置为
main window.Content
。显然,有许多子窗口,例如:

这对布局提出了一些挑战,因为我不能将其设置为
xxxx.Content
(我可以猜,但我不想用代码构建布局)。我该怎么办?我是否忽略了在XAML中执行此操作的能力?似乎XAML需要一个无参数构造函数,这显然不适用于DI的构造函数注入。谢谢


免责声明:我想使用纯DI。

很高兴您想使用纯DI。你的问题很好。我希望这本书的第二版能回答这个问题。如果我没记错的话,它没有一个简单的例子/答案

然而,纯DI的思想是所有依赖项在应用程序入口点a.k.a.组合根中都是可见的(使用构造注入)

在你的情况下,我会用以下方式将其链接起来: 公共部分类应用程序:应用程序 { 启动时受保护的覆盖无效(StartupEventArgs e) { 基础。启动时(e)

}

这样,主窗口依赖于StockHistoryViewModel,该模型依赖于StockHistoryService。 对于某些视图模型(弹出窗口/模式窗口等),我将使用DI的factory模式,以便仅在需要时创建视图模型。。。

我没有读过这本书。不过我希望这不是关于wpf的。可以在配置文件中定义连接字符串。可以使用资源字典(或两个)切换视图和视图模型.Oh.在应用程序的生命周期内保留dbcontext是个坏主意,除非它总是使用用户机器上的本地数据库。我通常只会切换出viewmodel依赖项(用于自动测试)。你是对的。在应用程序的生命周期中,Dbcontext的使用很差,但我的理解是,它应该是“每个表单的会话”,也称为每个视图的生命周期,不是吗?这是应用程序的入口点。用户启动应用程序,打开连接。他走开,开了一个8小时的会议……连接仍然存在l打开。每个窗口实例化一个dbcontext对于用户很少或本地数据库很少的小应用来说不是一个糟糕的主意。你可以通过这种方式进行更改跟踪。很多公司都很小,只有大约10个人会在一个应用中使用一个数据库。如果你有更多的用户和中央数据库,那就不太好了。
    string connectionString = @"Server=(localdb)\MSSQLLocalDB;Database=RouteMiningDB;Trusted_Connection=True;";
    RouteMiningDAL.RouteMiningDataContext db = new RouteMiningDAL.RouteMiningDataContext(new DbContextOptionsBuilder().UseSqlServer(connectionString).Options);
    IZIPCodeInfoRepository zipCodeRepo = new RouteMiningDAL.SQLZIPCodeInfoRepository(db);
    ZIPCodeInfoService zipCodeInfoService = new ZIPCodeInfoService(zipCodeRepo);
    StockHistoryService stockHistoryService = StockHistoryService();
    StockHistoryViewModel stockHistoryViewModel = new StockHistoryViewModel(stockHistoryService);

    ZIPCodeInfoViewModel zipCodeInfoViewModel = new ZIPCodeInfoViewModel(zipCodeInfoService, stockHistoryViewModel);
    ZIPCodeInfoView zipCodeInfoView = new ZIPCodeInfoView(zipCodeInfoViewModel);

    MainWindow mainWindow = new MainWindow();
    mainWindow.Content = zipCodeInfoView;
    mainWindow.Show();
}