快捷搜索:

CAL学习之二:容器

容器:

基于CAL实现的法度榜样,都是有一些松耦合的module构成,这些模块必要和Shell交互来实现数据的体现和相利用户的操作。由于他们都是松耦合的,以是他们必要一种互订交互和通讯的要领来实现所必要的营业功能。

为了共同这些不合的模块,基于CAL的利用法度榜样应用了依附注入的容器。依附注入的容器可以削减工具之间的依附,容器可以赞助我们实例化和掩护一个类的实例的生命周期。这些都是依据对容器的设置设置设备摆设摆设。在一个工具的创建历程中,容器把这个工具必要的实例都注入进去。假如它必要的实例还没有创建,容器会先去创建再注入。有些时刻,容器要把自己注入到工具中。比如一个module必要注入一个容器,这样module就可以把自己的view和service注册到容器中。

应用容器有以下好处:

容器省掉落你下边的麻烦:你必要应用一个组件还要弄清楚它的依附关系,以及创建和销毁它。

应用了容器,当你的类必要的组件的实现改变时,你的类不必要改变。

应用了容器,方便了你测试,由于你可以用一个假的依附。

容器使系统易于掩护,由于一个组件可以很轻易的被加入进来。

对付CAL来说:容器有以下好处:

容器把一个module的依附在他载入时注入。

容器被用来注册presenter和view。

容器创建Presenter和model,并把它们注入到view中。

容器可以注入办事,比如 regionmanager和event aggregator

容器可以用来注册模块相关的service。

下边的代码演示了injection是若何事情的,当PositionModule被container创建,它就会被注入regionManager和container。在RegisterViewsAndServices措施中,service,view和presenter都被注册。

publicPositionModule(IUnityContainer container, IRegionManager regionManager)

{

_container = container;

_regionManagerService = regionManager;

}

public voidInitialize()

{

RegisterViewsAndServices();

...

}

protected voidRegisterViewsAndServices()

{

_container.RegisterType(new ContainerControlledLifetimeManager());

_container.RegisterType();

_container.RegisterType();

...

}

应用Container

Container主要有两种用途:注册和解析。

注册:

在你要对一个工具的依附进行注入之前,依附的类型必须被注册到container中,注册一个类型必要传给container一个接口和实现这个接口的详细类型。你可以经由过程代码也可以经由过程设置设置设备摆设摆设来进行注册。

经由过程代码你有两种措施来注册类型和工具到container中。

你可以注册一个类型或者一个映射到container,在相宜的时刻,container会自己创建一个你指定类型的实例。

你可以注册一个已经天生的工具到container,container将会返回一个这个工具的引用。

this.container.RegisterType();

上边的代码用第一种措施来实现注册。

注册到container中的类型有一个生计期,可所以singleton或者是instance(每次都创建一个新的)。生计期可以在注册时或者在设置设置设备摆设摆设文件中指定。默认的生计期由container的实现抉择,比如Unity container默认的是instance模式。

解析(Resolving)

当一个类型被注册后,就可以被解析或者作为一个依附注入。

一样平常环境下,当一个类型解析出来,会有下边三种环境:

1.这个类型没有注册,container会抛出非常。

2.假如这个类型被注册为一个singleton模式,container将会返回一个singleton实例,假如这是第一次哀求,就创建一个,并且保留这个实例,以备后用。

假如这个类型不是singleton的,就天生一个实例返回,并不保留对实例的引用。

下边的代码便是从container中解析一个类型:

EmployeesPresenterpresenter = this.container.Resolve();

然则EmployeesPresenter的构造函数有下边的依附,这些依附在类型解析时会被注入实例。

publicEmployeesPresenter(IEmployeesView view, IEmployeesListPresenter listPresenter, IEmployeesControlleremployeeController)

{

this.View = view;

this.listPresenter = listPresenter;

this.listPresenter.EmployeeSelected +=newEventHandler>(this.OnEmployeeSelected);

this.employeeController = employeeController;

View.SetHeader(listPresenter.View);

}

什么时刻应用容器?

斟酌应用容器来进行注册和解析是否相宜。

你的利用是否能吸收注册和解析所耗损的机能。由于容器时使用了反射。

假如依附过多或者层次多深,机能耗损会显着增添。

假如一个组件没有任何依附,或者其他类型也不依附他,那么把它放到容器中就没有什么意义。

斟酌工具的生计期,是否用singleton?

假如一个组件是一个全局的办事,比如log,我们将它注册成单例模式。

假如一个组件对多个客户供给状态共享,你可以将它注册成单例模式。

假如有的依附每次有必要一个新的实例,你可以将它注册成一个非单例模式。

斟酌你是经由过程代码照样设置设置设备摆设摆设文件来设置设置设备摆设摆设container。

假如你想集中治理不合的办事,那就经由过程设置设置设备摆设摆设文件来设置设置设备摆设摆设。

假如你想根据不合的环境注册不合的service,那就要经由过程代码来设置设置设备摆设摆设。

假如你有模块级其余办事,那么就用代码来注册这些办事,由于这样就可以只在模块载入时再注册办事。

您可能还会对下面的文章感兴趣: