标签:des style blog http color io os 使用 ar
在初始化过程中,一种类型可以注册另外的类型,就像视图和服务。注册后就可以向整个容器提供它们的依赖关系,也可以通过其他类型来访问它们。为了做到这一点,类型需要在模块的构造器中向容器注入。以下代码是Commanding QuickStart示例代码中OrderModule是如何注册一个类型的。
public class OrderModule : IModule
{
public void Initialize()
{
this.container.RegisterType<IOrdersRepository, OrdersRepository>(new ContainerControlledLifetimeManager());
...
}
...
}
|
取决于你所选取的容器,注册也可以在代码外通过配置文件来实现。例如,参加第4章"Modular Application Development."中的"Registering Modules using a Configuration File"
注意:
与配置文件相比,通过代码来注册的优势在于,当模块被加载时才会注册。
MEF使用了基于属性的方式向容器中注册类型。因此,向容器中添加类型注册变的非常简单:为类型添加一个[Export]属性,如下代码所示,
[Export(typeof(ILoggerFacade))]
public class CallbackLogger: ILoggerFacade
{
}
|
使用MEF注册的另一种方法是将一个特定实例注册到容器中,如示例Modularity for Silverlight with MEF QuickStart中的QuickStartBootstrapper中注册函数ConfigureContainer所实现的这样,如下:
protected override void ConfigureContainer()
{
base.ConfigureContainer();
// Because we created the CallbackLogger and it needs to
// be used immediately, we compose it to satisfy any imports it has.
this.Container.ComposeExportedValue<CallbackLogger>(this.callbackLogger);
}
|
类型注册之后,它可被作为一个依赖来解析或者注册。当一个类型被解析时,容器需要创建一个新的实例,并将依赖关系注入到新创建的对象中。
一般来讲,当一个类型被解析时,会发生以下三种情况之一:
以下代码是Commanding QuickStart实例中的两个视图OrdersEditorView和OrdersToolBar是如何被容器解析,并且放置到其对应的区域中去的。
public class OrderModule : IModule
{
public void Initialize()
{
this.container.RegisterType<IOrdersRepository, OrdersRepository>(new ContainerControlledLifetimeManager());
// Show the Orders Editor view in the shell‘s main region.
this.regionManager.RegisterViewWithRegion("MainRegion",
() => this.container.Resolve<OrdersEditorView>());
// Show the Orders Toolbar view in the shell‘s toolbar region.
this.regionManager.RegisterViewWithRegion("GlobalCommandsRegion",
() => this.container.Resolve<OrdersToolBar>());
}
...
}
|
OrdersEditorPresentationModel构造方法中包含以下依赖(IOrdersRepository和OrdersCommandProxy),当它们被解析时,它们就被注入了。
public OrdersEditorPresentationModel( IOrdersRepository ordersRepository, OrdersCommandProxy commandProxy )
{
this.ordersRepository = ordersRepository;
this.commandProxy = commandProxy;
// Create dummy order data.
this.PopulateOrders();
// Initialize a CollectionView for the underlying Orders collection.
#if SILVERLIGHT
this.Orders = new PagedCollectionView( _orders );
#else
this.Orders = new ListCollectionView( _orders );
#endif
// Track the current selection.
this.Orders.CurrentChanged += SelectedOrderChanged;
this.Orders.MoveCurrentTo(null);
}
|
protected override DependencyObject CreateShell()
{
return this.Container.GetExportedValue<Shell>();
}
|
如实例Modularity for Silverlight with MEF QuickStart中的ModuleA,ILoggerFacade和IModuleTracker就是以如下代码的方式注入的。
[ImportingConstructor]
public ModuleA(ILoggerFacade logger, IModuleTracker moduleTracker)
{
if (logger == null)
{
throw new ArgumentNullException("logger");
}
if (moduleTracker == null)
{
throw new ArgumentNullException("moduleTracker");
}
this.logger = logger;
this.moduleTracker = moduleTracker;
this.moduleTracker.RecordModuleConstructed(WellKnownModuleNames.ModuleA);
}
|
另一种方式是使用属性注入,如Modularity for Silverlight with MEF QuickStart实例中的ModuleTracker类中向实例中注入ILoggerFacade的所示方法。
[Export(typeof(IModuleTracker))]
public class ModuleTracker : IModuleTracker
{
// Due to Silverlight/MEF restrictions, this must be public.
[Import] public ILoggerFacade Logger;
}
|
Prism 类库提供了UnityServiceLocatorAdapter 和 MefServiceLocatorAdapter. 这两个类都实现了通过扩展ServiceLocatorImplBase实现了ISeviceLocator接口,下面插图展示了类之间的关系


虽然Prism类库没有依赖或者实现任何特定的容器,但通常情况下,应用程序会依赖于某个特定的容器。这意味特定的应用程序会依赖某个容器,但是Prism类库并不直接和任何容器发生关系的是合理的。例如Stock Trader RI和一部分的QuickStart使用Prism并且依赖于Unity容器,而另一部分QuickStart和示例则依赖于MEF。
IServiceLocator
public interface IServiceLocator : IServiceProvider
{
object GetInstance(Type serviceType);
object GetInstance(Type serviceType, string key);
IEnumerable<object> GetAllInstances(Type serviceType);
TService GetInstance<TService>();
TService GetInstance<TService>(string key);
IEnumerable<TService> GetAllInstances<TService>();
}
|
public static class ServiceLocatorExtensions
{
public static object TryResolve(this IServiceLocator locator, Type type)
{
try
{
return locator.GetInstance(type);
}
catch (ActivationException)
{
return null;
}
}
public static T TryResolve<T>(this IServiceLocator locator) where T: class
{
return locator.TryResolve(typeof(T)) as T;
}
}
|
ModuleInitializer使用IServiceLocator在模块的加载过程中解析模块,如下代码所示:
IModule moduleInstance = null;
try
{
moduleInstance = this.CreateModule(moduleInfo);
moduleInstance.Initialize();
}
...
|
protected virtual IModule CreateModule(string typeName)
{
Type moduleType = Type.GetType(typeName);
if (moduleType == null)
{
throw new ModuleInitializeException(string.Format(CultureInfo.CurrentCulture, Properties.Resources.FailedToGetType, typeName));
}
return (IModule)this.serviceLocator.GetInstance(moduleType);
}
|
Prism4 文档翻译系列---第3章 管理组件间的依赖关系
标签:des style blog http color io os 使用 ar
原文地址:http://www.cnblogs.com/xixia/p/4014110.html