我的silverlight应用程序中有2个区域,利用棱镜4和统一主壳视图, Authenticated region和Non-authenticated region,以及一个菜单项。
在经过验证的区域内,根据注入的视图,有更多的子区域。
在加载应用程序时,我将看到登录屏幕“非认证区域”,登录时,我将出现在Authenticated区域。
当我点击菜单上的注销按钮时,我将再次看到登录视图。
但是当我第二次登录时,我在已通过身份验证的区域中加载的现有视图仍然存在。
我在注销时尝试了以下代码,删除了该区域的所有视图,但从容器中检索到的视图仍然是现有视图。
var regions = this.RegionManager.Regions;
foreach (var region in regions)
{
if (region.Name == this.AuthenticatedRegionName)
{
var views = region.Views;
foreach(var view in views)
{
region.Remove(view);
}
}
}
当我因某种原因调用请求导航时,我实际上得到了一些区域键未找到错误,但我认为主要问题在于容器。
我怎样才能告诉团结处理所有观点?
答案 0 :(得分:1)
由于您使用ContainerControlledLifetimeManager
进行查看,因此视图将在IUnityContainer
的生命周期内解析为同一实例。从区域中移除视图不会以任何方式将其从IUnityContainer
中删除,因为IUnityContainer
包含对视图的强引用。
更好的方法是不强制您的视图表现为单身人士。如果您希望Singleton行为将该行为推送到Service或ViewModel,它可以保留IUnityContainer
的生命期而不会产生任何不良影响。
View不应该以状态识别的方式运行;它应该保持无状态,因此应该避免强迫你的View充当单身人士。
如果您确定要在视图中使用Singleton行为,则可以使用ExternallyControlledLifetimeManager
来保存对View的弱引用。一旦所有对它的强引用都被删除,View就会被GC。
答案 1 :(得分:1)
我通过循环UnityContainer.Registration来解决它,并检查每个注册的LifetimeManagerType,如果它们是ContainerControlledLifetimeManager并且MappedToType等于我的基本视图模型类型,我为它创建一个新实例,就像设置它一样LOGOUT上的设定值。
var registrations = this.UnityContainer.Registrations;
if (registrations != null)
{
foreach (var registration in registrations)
{
if (registration.LifetimeManagerType != null &&
registration.LifetimeManagerType == typeof(ContainerControlledLifetimeManager) &&
registration.MappedToType.FullName.Equals("Main.ViewModelBase"))
{
var objectType = registration.LifetimeManager.GetValue().GetType();
var newInstance = Activator.CreateInstance(objectType, new object[]{this.UnityContainer});
registration.LifetimeManager.SetValue(newInstance);
}
}
}
不优雅,但它现在有效,干杯