在MVVM之后尝试使用WPF时使用纯DI(即没有框架)非常困难。我有Mark Seemann的书;然而,他对此的解决方案似乎与我提出的相似:
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
设置为mainWindow.Content
。显然有许多儿童Windows如:
这给布局带来了一些挑战,因为我不能真正将其设置为xxxx.Content
(我可以猜测,但我不想在代码中构建布局)。我该怎么做?我是否忽略了在XAML中执行此操作的能力?似乎XAML需要一个无参数构造函数,这显然不适用于DI的构造函数注入。谢谢!
免责声明:我想使用纯DI。
答案 0 :(得分:0)
很好,您想使用纯DI。您的问题很好。我希望本书的第二版能够回答它。如果我没记错的话,它没有一个简单的例子/答案。
但是,Pure DI的想法是,所有依赖关系(在使用构造注入时)都可以在应用程序入口点(也就是合成根目录)中看到。
在您的情况下,我将通过以下方式进行链接: 公共部分类应用程序:应用程序 { 受保护的重写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);
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();
}
}
以这种方式,主窗口取决于StockHistoryViewModel,后者取决于StockHistoryService。 对于某些视图模型(弹出/模态窗口等),我将使用带有DI的工厂模式,以便仅在需要时才创建视图模型。但这隐藏了视图模型的依赖... Dependency Injection vs Factory Pattern