【问题标题】:Clear all regions/views on Prism 4 (Silverlight) Logout清除 Prism 4 (Silverlight) 上的所有区域/视图注销
【发布时间】:2011-07-01 01:05:27
【问题描述】:

我的 silverlight 应用程序中有 2 个区域,利用 prism 4 和统一主 shell 视图, Authenticated region 和 Non-authenticated region,以及一个菜单项。

在经过身份验证的区域内,根据注入其中的视图,还有更多的子区域。

在加载应用程序时,我将看到登录屏幕“未验证区域”,登录时,我将显示在已验证区域。

当我点击菜单上的注销按钮时,我将再次看到登录视图。

但是当我第二次登录时,我在验证区域中加载的现有视图仍然存在。

我在注销时尝试了以下代码,以删除该区域的所有视图,但从容器中检索到的视图仍然是现有视图..

        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);                        
                }                    
            }
        }

当我出于某种原因调用请求导航时,我实际上收到了一些 region key not found 错误,但我认为主要问题出在容器上。

如何告诉 unity 处理所有视图?

【问题讨论】:

  • 您是否偶然将给定视图定义为 ContainerControlledLifetime? Region.Remove 应该足以从给定区域中删除视图。对给定视图类型调用容器上的 Resolve 应该提供一个新实例,除非您有一个生命周期管理器。
  • 感谢您的回复,我认为它确实有道理,是的,我的一些屏幕是 containerControlledLifetime(单例)...如何重置/清除生命周期管理器?
  • 添加了解决您问题的答案;提供不同的方法

标签: c# asp.net silverlight prism logout


【解决方案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);                           
                    }
                }
            }

不优雅,但现在可以使用,干杯

【讨论】:

  • 必须有强引用挂在视图上;也许通过事件
【解决方案2】:

由于您将ContainerControlledLifetimeManager 用于视图,因此视图将在IUnityContainer 的生命周期内解析为相同的实例。从区域中删除视图不会以任何方式将其从 IUnityContainer 中删除,因为 IUnityContainer 包含对视图的强引用。

更好的方法是不要强迫你的视图表现得像一个单例。如果您希望 Singleton 行为将该行为推送到 Service 或 ViewModel,它们可以在 IUnityContainer 的生命周期内保持不变,而不会产生任何不良影响。

视图不应以状态感知方式运行;它应该保持无状态,因此应该避免强迫您的视图充当单例。

如果您确定要在视图中使用单例行为,您可以使用 ExternallyControlledLifetimeManager,它将持有对视图的弱引用。一旦删除了对其的所有强引用,该视图就会被 GC'ed。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-13
    • 1970-01-01
    • 2019-04-07
    • 2021-08-02
    • 2019-01-16
    • 1970-01-01
    • 2021-09-26
    相关资源
    最近更新 更多