c# - How to create a Spec-Flow test for a Prism 7 app?
问题描述
I'm in the process of creating a new windows desktop app with Prism 7, and I started out with the new PrismApplication
base class that replaced the bootstrapper. Everything was fine until I created the (specflow-)tests.
I was used to re-using the original bootstrapper during initialization of the test-app, just modifying the registrations afterwards. That, transformed to the new Application
derived system looks like this:
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 ...
}
}
And a derived test-app that does everything but create the shell:
private class MyApp : App
{
protected override Window CreateShell()
{
return null;
}
}
Wrapped up in a BeforeScenario
hook to initialize the test-app:
[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 );
}
And a step to create the main window (CreateShell
replacement):
[When( @"I start the software" )]
public void WhenIStartTheSoftware()
{
_container.RegisterInstanceAs( _container.Resolve<App>().Container.Resolve<MainWindowViewModel>() );
}
So far, so good, this works. But only as long as you have just one scenario. As soon as the second scenario starts, we get an exception:
Cannot create more than one System.Windows.Application instance in the same AppDomain.
In the old days, this wasn't a problem, because the Bootstrapper
was just a regular class, as opposed to the PrismApplication
which is enforced to be a singleton by the framework.
Of course, I can move the whole registration stuff into a regular class, and use that to initialize the test-app, but this means essentially creating my own version of the bootstrapper on top of the PrismApplication
. Using the classic Bootstrapper
makes more sense to me, yet it will be dropped in a future release (as it's marked obsolete today).
解决方案
您将能够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);
推荐阅读
- c# - $expand=memberOf 返回的用户的组成员身份不可靠
- java - 在 Swing JPanel 中设置网格
- c++ - strcpy 到 C++ 中的多维数组
- jenkins - Cdancy Jenkins Rest 库创建凭证
- python-3.x - 嘿伙计们,我正在尝试构建一个基于 rfid 的阅读技术,其中 rfid antena 读取的 rfid 标签存储在一个变量中
- python - Pandas,将日期从 dd/mm/yyyy 格式化为 MMM dd/yy
- prolog - prolog中字典中的搜索词(W)
- flutter - 我的导航栏后面的黑色是从哪里来的?
- angular - 使用角度材料中的复选框来过滤数据库中的数据。错误 nameValue.toLowerCase 不是函数
- c - 非 void 函数不会在 C 中的所有控制路径中返回值