我为我的观点设置了PartCreationPolicy.NonShared
,但对于某些特定用户,我可以使用CreationPolicy.Shared
(为了提高性能),我不确定是否可以完成。因为我使用ServiceLocator
来获取视图的实例。喜欢
view = ServiceLocator.GetInstance<MyUserControl>("view_contract");
什么是最好的解决方案。我在Google上搜索过它,我找到了CompositionContainer.GetExports
的一些解决方案,但是
1-我无法在ViewModel中获得CompositionContainer
个实例。
2- In This Post,它写在 GetExport
下连续调用导出的Value将返回相同的值 实例,无论该部件是共享还是非共享 寿命。
请有人建议最好的解决方案和一些示例代码片段吗?
答案 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
}