我正在使用 Prism 7 创建一个新的 Windows 桌面应用程序,我最初使用了替换引导程序的新 PrismApplication
基类。一切都很好,直到我创建了 (SpecFlow-) 测试。
在测试应用程序初始化期间,我习惯于重复使用原始引导程序,只修改注册表。现在,基于新的派生自 Application
的系统,看起来像这样:
internal partial class App
{
protected override IContainerExtension CreateContainerExtension()
{
var containerExtension = new Prism.Unity.Ioc.UnityContainerExtension();
containerExtension.Instance.AddExtension( new LogExtension() );
return containerExtension;
}
protected override Window CreateShell()
{
return Container.Resolve<MainWindow>();
}
protected override void RegisterTypes( IContainerRegistry containerRegistry )
{
containerRegistry.Register<IConfiguration, AppSettingsConfiguration>();
containerRegistry.Register<IWindowsInterface, WindowsInterface>();
// ... a lot of registrations removed here ...
}
}
还有一个派生的测试应用程序,它做的一切都与创建shell无关:
private class MyApp : App
{
protected override Window CreateShell()
{
return null;
}
}
将初始化测试应用程序的操作包装在 BeforeScenario
钩子中:
[BeforeScenario]
public void InitializeApp()
{
var app = new MyApp();
app.Initialize();
var containerRegistry = (IContainerRegistry)app.Container;
containerRegistry.RegisterSingleton<TestWindowsInterface>();
containerRegistry.Register<IWindowsInterface,TestWindowsInterface>();
// ... some registration overrides removed here ...
_objectContainer.RegisterInstanceAs<App>( app );
}
创建主窗口的步骤(CreateShell
替代):
[When( @"I start the software" )]
public void WhenIStartTheSoftware()
{
_container.RegisterInstanceAs( _container.Resolve<App>().Container.Resolve<MainWindowViewModel>() );
}
到目前为止,一切都很好,这个方案可行。但只有当您只有一个方案时才有效。一旦第二种情况开始,我们就会收到异常:
Cannot create more than one System.Windows.Application instance in the same AppDomain.
在以前,这不是一个问题,因为Bootstrapper
只是一个普通的类,而不是由框架强制成为单例的PrismApplication
。
当然,我可以将整个注册过程放入普通类中,并使用它来初始化测试应用程序,但这意味着在PrismApplication
的基础上创建自己的版本的引导程序。使用经典的Bootstrapper
对我来说更有意义,但未来的版本中将删除它(因为它今天被标记为过时)。
[AfterScenario]
钩子来销毁/清理应用程序实例,也许?我不熟悉 Prism。 - Greg BurghardtViewModelLocator
可以在没有wpf的情况下工作。因此,我最接近视图模型,我的specflow-steps操作这些视图模型,模拟用户与视图交互(在测试期间不存在,因为它们是通过wpf的数据绑定创建的,而wpf本身不存在)。使用真实的应用程序是问题所在,因为每个应用程序域只能有一个,而nunit会将其重用于程序集中的所有测试。 - Haukinger