PRISM部分创建策略非共享/与MEF共享

时间:2013-02-19 07:49:54

标签: wpf prism mef containers service-locator

我为我的观点设置了PartCreationPolicy.NonShared,但对于某些特定用户,我可以使用CreationPolicy.Shared(为了提高性能),我不确定是否可以完成。因为我使用ServiceLocator来获取视图的实例。喜欢

view = ServiceLocator.GetInstance<MyUserControl>("view_contract");

什么是最好的解决方案。我在Google上搜索过它,我找到了CompositionContainer.GetExports的一些解决方案,但是

1-我无法在ViewModel中获得CompositionContainer个实例。

2- In This Post,它写在 GetExport

  

连续调用导出的Value将返回相同的值   实例,无论该部件是共享还是非共享   寿命。

请有人建议最好的解决方案和一些示例代码片段吗?

1 个答案:

答案 0 :(得分:2)

据我所知,您有一些“业务逻辑”来区分共享和非共享视图(例如,取决于用户类型)。我认为这不应该在您的DI容器中处理......

如果你想用“prism-style”实现这个目的,你可以在ViewModel中使用prism INavigationAware接口:view和viewModel是非共享的,你可以通过导航激活/构建它(工作原理)完美与MEF)。将“共享”/“非共享”的业务逻辑放入“IsNavigationTarget”方法中。 Prism将自动调用此方法并仅在需要时创建新的视图实例。

以下是一些代码:

视图(不要忘记视图名称作为导航目标!):

[Export(Constants.ViewNames.MyFirstViewName)] // The Export Name is only needed for Prism's view navigation.
[PartCreationPolicy(CreationPolicy.NonShared)] // there may be multiple instances of the view => NO singleton!!
public partial class MyFirstView
{ ... }

ViewModel:

    [PartCreationPolicy(CreationPolicy.NonShared)] 
    [Export]
    public class MyFirstViewModel: Microsoft.Practices.Prism.Regions.INavigationAware
    {
       #region IINavigationAware
        // this interface ships with Prism4 and is used here because there may be multiple instances of the view
        // and all this instances can be targets of navigation.

        /// <summary>
        /// Called when [navigated to].
        /// </summary>
        /// <param name="navigationContext">The navigation context.</param>
        public override void OnNavigatedTo(NavigationContext navigationContext)
        {                    
            ...
        }

        /// <summary>        
        /// </summary>
        public override void OnActivate()
        {
            ...
        }

        /// <summary>
        /// Determines whether [is navigation target] [the specified navigation context].
        /// </summary>
        /// <param name="navigationContext">The navigation context.</param>
        /// <returns>
        ///     <c>true</c> if [is navigation target] [the specified navigation context]; otherwise, <c>false</c>.
        /// </returns>
        public override bool IsNavigationTarget(NavigationContext navigationContext)
        {
            // use any kind of busines logic to find out if you need a new view instance or the existing one. You can also find any specific target view using the navigationContext...
            bool thereCanBeOnlyOneInstance = ...
            return thereCanBeOnlyOneInstance;
        }    

        #endregion
}