我正在使用基于棱镜视图的导航和RequestNaving方法。
我解决的问题是我必须将所有视图模型注册到容器中:
container.RegisterType<object, InboxView>("InboxView");
这非常冗长,需要我想要注册的所有视图类型的列表。
有什么解决方法吗?
我认为请求导航应该是通用的:
IRegion.RequestNavigate<TView>();
并应执行以下操作:
- 解析视图
- 在应
typeof(TView).Name
的区域中为视图指定一个名称 - :)执行实际的导航请求
- 请在棱镜问题列表中为我的建议摘要投票。
我知道你想得到什么,但提出的解决方案并没有真正满足区域管理器的设计目标。特别:
- 区域请求与类型无关。如果您没有从模块 B 引用模块 A 中的类型,但想要导航到该类型,那么如果不将这些模块相互引用或将这些类型重构到第三个程序集中,如何导航?
- 区域可以根据需要具有任意数量的特定类型的视图。您建议的解决方案会人为地将特定类型的视图数量限制为 1,而区域目前的工作方式并非如此。
不过,这并不能回答您的问题。
至于减少冗长,除了推出自己的解决方案之外,您无能为力,该解决方案将您想要的行为封装在 RegionManager 面前。就我个人而言,我不会走这条路,但这肯定是你可以做的事情。您可以将其编写为您自己的服务,或者只是IRegionManager或IRegion上的扩展方法。
public interface IMyNavigationService
{
//Your own implementation could use (typeof(T)).Name (or
//AttributedModelServices.GetContractName(typeof(T)) if using MEF)
//as the Key, if thatis appropriate for your solution
//(1 instance T per region and references to T from all Modules)
void RequestNavigation<T>();
}
看起来切换到 MEF 作为 IoC 容器可能有助于满足您的需求......这只取决于你不关心这些代码行中的哪几行。对我来说,我不喜欢RegisterType<object, InboxView>
. MEF 等效项为:
[Export]
public class InboxView { .. }
您可以在此处提供合约名称 ( [Export("InboxView")]
),但默认情况下它将提供合约名称 AttributedModelServices.GetContractName(typeof(InboxView))
。只要您选择的任何内容与您在IMyNavigationService的实现中选择生成名称的方式一致,它应该可以正常工作。
这是同样的事情,但使用扩展方法实现(使用 MEF 实现...如果您使用 Unity,您可以选择其他一些密钥生成方法...您只需要在方法中添加该类型的注册)
public static class RegionExtensions
{
public static void RequestNavigate<T>(this IRegion region)
{
region.RequestNavigate(AttributedModelServices.GetContractName(typeof(T)));
}
}
如果您对将所有内容切换到 MEF 感到紧张,有一个 MefContrib 项目可以让这变得更容易......它基本上将 Unity 和 MEF 合二为一。
希望这有所帮助。