我正在使用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 ...
}
}
还有一个衍生的测试应用程序,除了创建外壳外,它会执行所有操作:
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
引导程序on top版本。对我来说,使用经典的Bootstrapper
更有意义,但它将在将来的版本中删除(因为今天标记为过时的)。
您将能够使用从Application
派生的类来创建MarshalByRefObject
类的多个实例:
public class AppDomainWrapper : MarshalByRefObject
{
public void DoSomething()
{
var app = new MyApp();
app.Initialize();
...
app.Shutdown();
}
}
示例用法:
AppDomain appDomain = AppDomain.CreateDomain("AppDomain");
AppDomainWrapper app = appDomain.CreateInstanceAndUnwrap(typeof(AppDomainWrapper).Assembly.FullName, typeof(AppDomainWrapper).FullName) as AppDomainWrapper;
app.DoSomething();
AppDomain.Unload(appDomain);