Prism-Unity问题:ConfigureRegionAdapterMappings中无法解析IRegionBehaviorFactory
解决Prism + Unity 7.0中IRegionBehaviorFactory激活错误的方案
我来帮你搞定这个问题,你的核心问题出在容器实例不一致以及Unity 7.0 ServiceLocator命名空间适配上。咱们一步步来修正:
1. 抛弃自定义UnityContainer,使用UnityBootstrapper内置容器
你自己new了一个uc实例,但UnityBootstrapper基类已经维护了一个Container属性,这会导致ServiceLocator和Prism内部使用的容器不是同一个,自然找不到依赖。直接删掉自定义的uc,改用基类提供的Container。
2. 修正ConfigureServiceLocator方法
确保ServiceLocator绑定的是基类的容器,而非自定义实例:
protected override void ConfigureServiceLocator() { var locator = new UnityServiceLocator(Container); ServiceLocator.SetLocatorProvider(() => locator); }
这里不需要调用base.ConfigureServiceLocator(),因为基类的实现是针对旧版Unity的,Unity 7.0里咱们直接用Unity.ServiceLocation的实现即可。
3. 调整ConfigureContainer方法
移除对uc的引用,改用基类Container,并且不需要手动注册IServiceLocator(UnityServiceLocator已经和容器绑定,Prism能自动识别):
protected override void ConfigureContainer() { base.ConfigureContainer(); Container.RegisterType<IRegionBehaviorFactory, RegionBehaviorFactory>(); Application.Current.Resources.Add("IoC", Container); }
4. 修正ConfigureRegionAdapterMappings方法
直接用基类Container解析IRegionBehaviorFactory,避免ServiceLocator的额外开销,同时确保容器一致性:
protected override RegionAdapterMappings ConfigureRegionAdapterMappings() { var mappings = base.ConfigureRegionAdapterMappings(); var regionBehaviorFactory = Container.Resolve<IRegionBehaviorFactory>(); mappings.RegisterMapping(typeof(RadPaneGroup), new RadPaneGroupRegionAdapter(regionBehaviorFactory)); return mappings; }
完整修正后的Bootstrapper代码
public class Bootstrapper : UnityBootstrapper { protected override void ConfigureServiceLocator() { var locator = new UnityServiceLocator(Container); ServiceLocator.SetLocatorProvider(() => locator); } protected override DependencyObject CreateShell() { return Container.Resolve<wMain>(); // 直接用容器解析,比ServiceLocator更直接 } protected override void InitializeShell() { Application.Current.MainWindow = (wMain)this.Shell; Application.Current.MainWindow.Show(); } protected override IModuleCatalog CreateModuleCatalog() { return new ConfigurationModuleCatalog(); } protected override void ConfigureContainer() { base.ConfigureContainer(); Container.RegisterType<IRegionBehaviorFactory, RegionBehaviorFactory>(); Application.Current.Resources.Add("IoC", Container); } protected override RegionAdapterMappings ConfigureRegionAdapterMappings() { var mappings = base.ConfigureRegionAdapterMappings(); var regionBehaviorFactory = Container.Resolve<IRegionBehaviorFactory>(); mappings.RegisterMapping(typeof(RadPaneGroup), new RadPaneGroupRegionAdapter(regionBehaviorFactory)); return mappings; } }
关键原因解释
- Unity 7.0将
Microsoft.Practices.Unity.IServiceLocator移到了Unity.ServiceLocation命名空间下,Prism的RegionBehaviorFactory需要与当前容器绑定的ServiceLocator实例,你之前用自定义容器创建的ServiceLocator和Prism内部容器不匹配,导致激活失败。 - UnityBootstrapper已经为你处理了大部分容器初始化工作,自定义容器实例会打破Prism的内部依赖链,所以必须统一使用基类提供的
Container。
内容的提问来源于stack exchange,提问作者Matteo Beretta
相关产品推荐
相关产品推荐

