背景
基于Prism库的应用程序是复合应用程序,可能包含许多松散耦合的类型和服务。他们需要进行交互以提供内容并根据用户操作接收通知。因为它们是松散耦合的,所以它们需要一种相互交互和通信的方式来提供所需的业务功能。为了将这些不同的部分组合在一起,基于Prism库的应用程序依赖于依赖注入容器,依赖注入容器通过提供实例化类实例的工具并根据容器的配置管理其生命周期来减少对象之间的依赖关系。在对象创建期间,容器会将对象所需的所有依赖项注入其中。如果尚未创建这些依赖项,则容器首先创建并解析它们的依赖项。在某些情况下,容器本身被解析为依赖项,例如,当使用Unity应用程序块(Unity)作为容器时,模块会注入容器,因此可以使用该容器注册其视图和服务。
使用优势
使用容器有几个好处:
- 容器不需要组件来定位其依赖关系或管理它们的生命周期。
- 容器允许交换已实现的依赖项而不影响组件。
- 容器通过允许模拟依赖项来促进可测试性。
- 容器通过允许将新组件轻松添加到系统中来提高可维护性。
在基于Prism库的应用程序的上下文中,容器具有特定的优点:
- 容器在加载时将模块依赖项注入模块。
- 容器用于注册和解析视图模型和视图。
- 容器可以创建视图模型并注入视图。
- 容器注入组合服务,例如区域管理器和事件聚合器。
- 容器用于注册特定于模块的服务,这些服务是具有模块特定功能的服务。
使用步骤
1 使用Unity容器注册类型
public class OrderModule : IModule { public void Initialize() { this.container.RegisterType<IOrdersRepository, OrdersRepository>(new ContainerControlledLifetimeManager()); ... } ... }
在上面的代码中我们向容器中注入了一个IOrdersRepository的具体类型和实现,这个在整个容器的生命周期内都可以被解析,下面我们来看看该怎样去解析这个注入容器中的对象。
2 解析容器中的注册的类型
通常,在解析类型时,会发生以下三种情况之一:
- 如果尚未注册该类型,则容器将引发异常。
注意:某些容器(包括Unity)允许您解析尚未注册的具体类型。
- 如果类型已注册为单例,则容器将返回单例实例。如果这是第一次调用该类型,则容器会创建它并保留它以供将来调用。
- 如果类型尚未注册为单例,则容器将返回新实例。
注意:默认情况下,使用MEF注册的类型是单例,容器包含对象的引用。在Unity中,默认情况下会返回新的对象实例,并且容器不会维护对该对象的引用。
public OrdersEditorViewModel(IOrdersRepository ordersRepository, OrdersCommandProxy commandProxy) { this.ordersRepository = ordersRepository; this.commandProxy = commandProxy; // Create dummy order data. this.PopulateOrders(); // Initialize a CollectionView for the underlying Orders collection. this.Orders = new ListCollectionView( _orders ); // Track the current selection. this.Orders.CurrentChanged += SelectedOrderChanged; this.Orders.MoveCurrentTo(null); }
在上面的例子中我们可以看到只要是在我们需要使用到的地方通过构造函数传入对应的类型信息这样一来注入容器就可以自动为我们解析到之前注入到容器内部的类型信息,当然还有一种方式就是通过属性注入到当前类中去。所以这里就涉及到注入依赖的两种主要的方式,一种是通过构造函数注入,另外一种是通过属性注入的方式,这个在使用的时候需要根据自己的需要进行灵活运用。