我是靠谱客的博主 简单眼睛,最近开发中收集的这篇文章主要介绍理解MVVMLight—Laurent Bugnion的设计思想——〉Service Locator Pattern,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

  目前Team在写WPF项目的时候,往往设计一个Business Manager类,它是一个Singleton,用来处理一些特定的业务,其实可以理解为Mvc中的Control,也可以理解为一个Service。当业务逻辑的需求需要应用程序的View上交互动作操作,View调用Service来完成特定的任务,如点击PhotoApp,PhotoApp调用Sevice的加载图片方法加载View所需的图片集合。通常最简单的办法是在App Load或者初始化时new创建一个Service对象,或者再高级一点,使用Factory Pattern来Decoupling(解耦)View与Serivce的具体实现部分,通过Config方便的获取该Serivce的实例。然而上述两种做法都有各自的缺陷,下面列述:

  1.在View中直接维护对Serivce的引用,伪代码:

1 this.Load += Onload;
2
3 private void Onload(object sender,EvenetArgs e){
4 
Service.Instance.Open();
5 }

  上面是我们项目中经常见到的写法,这样直接造成View与Service之间的依赖关联,当需要替换服务的实现时,必须修改View中调用Service的部分并重新编译Solution。即使采用Factory Pattern来通过Config动态获取Service实例,也无法针对不同的Service向View提供View所需的服务实例。

  2.由于这种依赖关联,使得项目的开发过程受到约束。在实际开发过程中,View开发和Service开发可能是同步进行的,很有可能当View需要调用Service时,Service还没开发完。遇到这种问题,通常先把坑留着,或者自己用Proxy Pattern写个Demo方法,等Service完成后再集成,这种做法不仅费时,增加了合成风险,也使责任不明,更加增加了出错风险提升了测试的复杂度。

  3.针对View的Unit Test变得十分复杂,如果要做Unit Test,无法使用Service Stub来解决View与Service的依赖关系。

  4.在View的Code-Behind中可能存在多处Call Service的Instance,在这种情况下,Service.Instance.Method会散步于整个应用程序中,造成一段代码存在多个副本,几何级的增加了维护和排错的成本。

  5.当View需要Call多个Service时,不同Service 初始化各自的Instance的方式可能存在差异,Coder必须了解所有Service的初始化的API,才能在代码中正确使用这些Service。

  6.某些Service的初始化过程需要耗费大量资源,多次重复初始化,大大增加应用程序的资源占用和性能消耗,项目中需要一个管理Service初始化过程的机制,在统一初始化接口的同时,需要为应用程序提供部分缓存功能,如文稿页面,相册图片等。

  Laurent Bugnion所写的轻量级框架MVVMLight使用Service Locator Pattern来解决上述的问题。

 

  Service Locator Pattern(服务定位器模式)

    它能够为应用程序中Service的创建和初始化提供一个定位,并解决了上文中所提到的各种设计和开发问题。Service Locator Pattern主要有以下几种参与者:

   1.Service:    

    Service是Service Locator需要返回给调用方的Instance。比如Service Locator(ViewModel Locator)可以根据调用方的需要,View从Service(ViewModel)从网络获取信息,或者View从Service(ViewModel)从本地文件系统获取信息。在这种情形下,这两种Service可能会有着不同的接口:对于前者,它只需要接收一个参数(即需要信息列表)就可以完成获取任务;而对于后者而言,它不仅要获得信息列表,而且还要获得一个正确的文件路径。因此,在实际应用中,我们通常会为不同的Service类型设计不同的接口,而Service Locator则应该根据调用方给定的Service Type,返回相应的Service Instance。

  2.Service Factory

    Service Factory是Factory Pattern的一种实现,它的职责是创建并初始化某种类型的Service。不同的Service Type有其特定的Service Factory,在实际应用中,Service Factory厂与一个特定的Service Intface所对应。使用Service Factory不仅可以Coupling Service的定义部分和具体实现部分,应用程序无需重新编译即可变更Service的不同实现方式,而且对于初始化过程需要消耗大量资源的Service而言,Service Factory还能够提供缓存功能,从而提高应用程序的性能。

  3.Initial Context

    由于不同的Service需要由不同的Service Factory New和实现Initialization,因此对于Service Locator来说,还需要一个特定的Locator来统一管理这些Service Factory,Initial Context就充当了这个角色。在调用方向Service Locator请求一个Service Instance时,Service Locator通过InitialContext获得Service Factory的Instance,然后由Service Factory new service并返回给调用方。使用Initial Context的优点是,它简化了Service Locator的职责,并为Service Factory的管理和缓存提供了有力保障。

  4.Service Locator

    Service Locator为调用方获得所需Service的Instance提供了定位。

  Service Locator Pattern 的类图和时序图请参考Wiki,下面给出的参考资料链接中有,这里就不再引用。

  MVVMLight 实现:

  1.ViewModelLocator(Service Locator)  

1 <?xml version="1.0" encoding="utf-8"?>
2 <Application x:Class="WpfApplication1.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" StartupUri="MainWindow.xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:vm="clr-namespace:WpfApplication1.ViewModel" mc:Ignorable="d">
3
<Application.Resources>
4
<ResourceDictionary>
5
<vm:ViewModelLocator x:Key="Locator" d:IsDataSource="True" />
6
<ResourceDictionary.MergedDictionaries></ResourceDictionary.MergedDictionaries>
7
</ResourceDictionary>
8
</Application.Resources>
9 </Application>

  2. SimpleIoc (Initial Context)

  

 1 using GalaSoft.MvvmLight;
 2 using GalaSoft.MvvmLight.Ioc;
 3 using Microsoft.Practices.ServiceLocation;
 4
 5 namespace WpfApplication1.ViewModel
 6 {
 7
/// <summary>
 8
/// This class contains static references to all the view models in the
 9
/// application and provides an entry point for the bindings.
10
/// </summary>
11
public class ViewModelLocator
12 
{
13
/// <summary>
14
/// Initializes a new instance of the ViewModelLocator class.
15
/// </summary>
16
public ViewModelLocator()
17 
{
18
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
19
20
////if (ViewModelBase.IsInDesignModeStatic)
21
////{
22
////
// Create design time view services and models
23
////
SimpleIoc.Default.Register<IDataService, DesignDataService>();
24
////}
25
////else
26
////{
27
////
// Create run time view services and models
28
////
SimpleIoc.Default.Register<IDataService, DataService>();
29
////}
30
31
SimpleIoc.Default.Register<MainViewModel>();
32 
}
33
34
public MainViewModel Main
35 
{
36
get
37 
{
38
return ServiceLocator.Current.GetInstance<MainViewModel>();
39 
}
40 
}
41
42
public static void Cleanup()
43 
{
44
// TODO Clear the ViewModels
45 
}
46
}

  3.MainWindow.DataContext Binding MainViewModel

    是为View作为调用方引用Service的实例

 

  具体使用案例:

  1.CodeProject:http://www.codeproject.com/Articles/297624/Implementing-MVVM-Light-with-Structure-Map

  2.GBTouch Team:参考VoteApp实现

 

  参考资料:

  Deep Dive MVVM: http://channel9.msdn.com/events/MIX/MIX11/OPN03

  MVVMLight:http://www.galasoft.ch/mvvm/

  Service Locator Pattern(Wiki) http://en.wikipedia.org/wiki/Service_locator_pattern

  Service Locator Pattern(MSDN)http://msdn.microsoft.com/en-us/library/ff648968.aspx

  Dependency Injection(MSDN)http://msdn.microsoft.com/en-us/library/dd458879.aspx

  IOC[Inversion of Control]http://msdn.microsoft.com/en-us/library/dd458907.aspx

 

 

转载于:https://www.cnblogs.com/tmywu/archive/2013/05/26/3099349.html

最后

以上就是简单眼睛为你收集整理的理解MVVMLight—Laurent Bugnion的设计思想——〉Service Locator Pattern的全部内容,希望文章能够帮你解决理解MVVMLight—Laurent Bugnion的设计思想——〉Service Locator Pattern所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(39)

评论列表共有 0 条评论

立即
投稿
返回
顶部