大佬教程收集整理的这篇文章主要介绍了Prism研究(for WPF & Silverlight)7.View Injection和View Discovery,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
我们晓得,每个@H_741_19@module中,实现了IModule接口的@H_741_19@module类,都要实现该接口的Initialize方法,一方面要注册一些自定义的接口和实现了该接口的类,为接下来的依赖注入做准备;另一方面,就是为Region加载View并显示(初始化View)。
加载View的方式,分为View Injection和View Discovery两类,各有千秋。
1. View Injection,指的是RegionManager,它的属性Regions,这是一个集合类RegionCollection,同时还实现了基于RegionName的内部索引。于是,我们可以这样编写代码:
View-first:
this.regionManager.Regions["MainRegion"].Add(new HelloWorldView());
Presenter-first:
this.regionManager.Regions["MainRegion"].Add(this.container.Resolve<HelloWorldPresenter>().View);
有关View-first和Presenter-first的概念,我们在下一节中专门介绍。
View Injection的视图如下,有点像中介者模式吧,那个Registry就是一个@H_741_19@mediator:
2. View Discovery,指的是RegionViewRegistry的RegisterViewWithRegion方法,有2个重载:
public void RegisterViewWithRegion(String regionName,Type viewTypE)
this.RegisterViewWithRegion(regionName,() => this.CreateInstance(viewTypE));
public void RegisterViewWithRegion(String regionName,Func<object> getContentDelegatE)
this.registeredContent.Add(regionName,getContentDelegatE);
this.onContentRegistered(new ViewRegisteredEventArgs(regionName,getContentDelegatE));
我们看到,第1个方法是基于第2个方法的,就是把RegionName和一个delegate(用于创建View的一个实例)同时注册到字典ListDictionary<String,Func<object>>和委托链WeakDelegatesmanager中。
于是我们可以这样编写代码:
View-first:
this. RegionViewRegistry.RegisterViewWithRegion("MainRegion",typeof(Views.HelloWorldView));
Presenter-first:
this. RegionViewRegistry.RegisterViewWithRegion("MainRegion",
() => this.container.Resolve<IHelloWorldPresenter>().View);
有关View-first和Presenter-first的概念,我们在下一节中专门介绍。
View Discovery的视图如下,看这个图让我想起了GOF中的注册工厂:
View Injection和View Discovery,本来就是2个不同类——RegionManager和RegionViewRegistry的不同实现方式,连存储结构都不同,前者是集合,后者是字典。相对而言,前者的实现更直接一些(来一个招呼一个),后者比较绕(先对号入座,然后再用到谁招呼谁)。
存储结构的不同,使得二者在性能上有很大差异。RegionManager的Regions属性是一个集合,所以可以手动添加或移除Region中的View(使用集合的Add或Remove方法),尤其是移除功能,可以释放不再使用的内存。
相对而言,RegionViewRegistry在内部使用字典来存储View,它的RegisterViewWithRegion方法就是把View添加到这个字典中,但是,由于这个字典是私有的,不对外暴露,所以我们无法使用它的Remove方法来移除View。这是因为,我们存储到字典中的View都是弱引用,再回顾一下:
this. RegionViewRegistry.RegisterViewWithRegion("MainRegion",typeof(Views.HelloWorldView));
这里typeof(Views.HelloWorldView)就是一个弱引用,我们知道,.NET会自动回收不再使用的内存,所以,理想情况下,不再使用这个View时,该View所占的内存就会被自动回收了。但是,自动回收内存在什么时候发生呢?没人知道。所以,系统越来越慢,就是因为RegionViewRegistry的这个方法导致的。
既然不好用,那为什么还要设计出RegionViewRegistry呢?
说起来话长了。这要从Prism的第1版说起。话说,那时Prism中只有View Injection机制,也就是说,只有RegionManager类。后来,大家发现RegionManager类也有不好的地方,就是在嵌套Region的时候,每一级Region中都要写点Regions[“RegionName”].Add方法,而且还要care层次间的关系,是不是觉得很麻烦?而且Prism经常会报错说找不到RegionName,以致于抛出异常(关于这一点,请参见我的另一篇文章)。为了方便开发,p&p小组在Prism第2版中提供了RegionViewRegistry类,及其RegisterViewWithRegion方法,于是我们可以在任何地方使用该方法,而不需要在各自的View中编写相应的代码。但是,简单是要付出代价的,那就是性能,上文已经分析过。
同时,Prism框架把RegisterViewWithRegion也作为扩展方法添加到了RegionManager类中,实际上还是调用RegionViewRegistry类的RegisterViewWithRegion方法。于是,形成了一个组合关系。
本来设计思想是蛮好的,可以屏蔽RegionViewRegistry类,对Client而言,只有RegionManager类,它同时具有RegisterViewWithRegion方法和Regions[“RegionName”]属性(前者是弱引用方式,后者是强引用方式)。
但是,不知是微软p & p的那个DPE大脑进水,在Prism文档和示例又同时使用了RegionViewRegistry的RegisterViewWithRegion方法。这就违背了设计的初衷。于是,我们糊涂了,不知道什么时候该使用哪一个类的哪一个方法,甚至开始怀疑人生。
以上是大佬教程为你收集整理的Prism研究(for WPF & Silverlight)7.View Injection和View Discovery全部内容,希望文章能够帮你解决Prism研究(for WPF & Silverlight)7.View Injection和View Discovery所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。