语境
我有一InteractionWindowPresenter
堂课负责创建 Windows。其中一些可能是模态的,我想保留打开的模态窗口数量的计数器,以便通知应用程序的其他部分。
因此,我_modalsCount
在类中添加了一个变量,每当打开或关闭模式窗口时都会更新:
public class InteractionWindowPresenter<TWindow, TNotification>
where TWindow : System.Windows.Window
where TNotification : Prism.Interactivity.InteractionRequest.INotification
{
private static int _modalsCount = 0;
...
private bool _useModalWindow;
public InteractionWindowPresenter(InteractionRequest<TNotification> request,
bool useModalWindow = false)
{
_useModalWindow = useModalWindow;
}
public void Show()
{
var window = ...
window.Closed += (s, e) =>
{
if (_useModalWindow)
{
_modalsCount = Math.Max(0, --_modalsCount);
if (_modalsCount == 0)
ServiceLocator.Current.GetInstance<IEventAggregator>()
.GetEvent<ModalStatusChanged>().Publish(false);
}
};
if (_useModalWindow)
{
_modalsCount++;
ServiceLocator.Current.GetInstance<IEventAggregator>()
.GetEvent<ModalStatusChanged>().Publish(true);
window.ShowDialog();
}
else
window.Show();
}
}
初始化后,每个Prism 模块- 即。每个类都实现IModule
- 实例化一个 InteractionWindowPresenter
必须在 Window 上显示并持有对它的引用的每个视图。例如:
[ModuleExport("ClientsModule", typeof(Module),
DependsOnModuleNames = new[] { "RibbonModule", "ClientsModelModule" },
InitializationMode = InitializationMode.WhenAvailable)]
public class Module : IModule
{
InteractionWindowPresenter<ClientSelectionWindow, ClientSelection> _selectionPresenter;
public void Initialize()
{
_selectionPresenter =
new InteractionWindowPresenter<ClientSelectionWindow, ClientSelection>
(Interactions.ClientSelectionRequest, useModalWindow: true);
}
}
该类InteractionWindowPresenter
在所有模块以及其他基础结构组件直接引用的基础结构组件中定义。启动器应用程序不引用它,它只是一个MefBootstrapper
. 因此,MEF用于合成。
问题
在初始化行设置断点_modalsCount
表明在InteractionWindowPresenter
创建实例时不会执行断点。相反,它是在每个模块中使用变量的第一次(也是唯一一次)执行 - 即。第一次Show
从每个模块调用该方法。因此,每个模块都有自己的价值,在该特定模块的所有实例中共享。
我知道懒惰的评估是由于beforefieldinit
. 但是,我希望整个应用程序而不是每个模块的评估只发生一次。
我还尝试在静态构造函数中执行初始化:
static int _modalsCount;
static InteractionWindowPresenter()
{
_modalsCount = 0;
}
在这种情况下,静态构造函数在实例构造函数执行之前被调用,但每次创建实例时。因此,变量似乎不再是静态的。
据我了解,static
变量每AppDomain
. 因此,由于我所有的程序集(模块和基础结构)都在同一个AppDomain
中,因此不应该发生这种情况。这两个假设中的任何一个我错了吗?
到目前为止采用的解决方法
创建一个简单的类来保存计数器可以避免这个问题:
static class ModalsCounter
{
private static int _modalsCount = 0;
public static int Increment()
{
return ++_modalsCount;
}
public static int Decrement()
{
_modalsCount = Math.Max(0, --_modalsCount);
return _modalsCount;
}
}
因此将调用替换为_modalsCount
:
ModalsCounter.Increment();
ServiceLocator.Current.GetInstance<IEventAggregator>()
.GetEvent<ModalStatusChanged>().Publish(true);
和:
if (_useModalWindow && ModalsCounter.Decrement() == 0)
ServiceLocator.Current.GetInstance<IEventAggregator>()
.GetEvent<ModalStatusChanged>().Publish(false);
那么我在这里错过了什么?我是否以某种方式误解了静态变量的生命周期和范围,还是 Prism 模块和/或 MEF 惹恼了我?