zoukankan
html css js c++ java
EnterLib ObjectBuild vs Castle WindsorContainer
首先来看一下在Castle项目中用于示范其Ioc功能的一个小例子:
1
:
public
interface
IEmailSender
2
:
{
3
:
void
Send(String from, String to, String message);
4
: }
5
:
6
:
public
interface
ITemplateEngine
7
:
{
8
: String Process(String templateName);
9
: }
10
:
11
:
public
interface
INewsletterService
12
:
{
13
:
void
Dispatch(String from, String[] targets, String message);
14
: }
15
:
16
:
public
class
SmtpEmailSender : IEmailSender
17
:
{
18
:
private
String _host;
19
:
private
int
_port;
20
:
21
:
public
SmtpEmailSender(String host,
int
port)
22
:
{
23
: _host
=
host;
24
: _port
=
port;
25
: }
26
:
27
:
public
virtual
void
Send(String from, String to, String message)
28
:
{
29
: Console.WriteLine(
"
Sending e-mail from {0} to {1} with '{2}'
"
,
30
: from, to, message );
31
: }
32
: }
33
:
34
:
public
class
NVelocityTemplateEngine : ITemplateEngine
35
:
{
36
:
public
virtual
String Process(String templateName)
37
:
{
38
:
return
"
Some template content
"
;
39
: }
40
: }
41
:
42
:
public
class
SimpleNewsletterService : INewsletterService
43
:
{
44
:
private
IEmailSender _sender;
45
:
private
ITemplateEngine _templateEngine;
46
:
47
:
public
SimpleNewsletterService
48
: (IEmailSender sender, ITemplateEngine templateEngine)
49
:
{
50
: _sender
=
sender;
51
: _templateEngine
=
templateEngine;
52
: }
53
:
54
:
public
void
Dispatch(String from, String[] targets, String message)
55
:
{
56
: String msg
=
_templateEngine.Process(message);
57
:
58
:
foreach
(String target
in
targets)
59
:
{
60
: _sender.Send(from, target, msg);
61
: }
62
: }
63
:
64
: }
Ioc的作用就是能够利用容器自动的构建出一个SimpleNewsletterService对象,而不是由用户直接的创建并传递其参数,这样就可以进一步降低对象与对象之间耦合程度,从而方便的替换其实现。在上例中将采用构造器设值的方式,来实现对象依赖关系的注入。下面给出Castle的实现方式:
BasicUsage.xml
<?
xml version
=
"
1.0
"
encoding
=
"
utf-8
"
?>
<
configuration
>
<
components
>
<
component id
=
"
smtpemailsender
"
>
<
parameters
>
<
host
>
localhost
</
host
>
<
port
>
110
</
port
>
</
parameters
>
</
component
>
</
components
>
</
configuration
>
1
:
public
static
void
Main()
2
:
{
3
: IWindsorContainer container
=
4
:
new
WindsorContainer(
new
XmlInterpreter(
"
../BasicUsage.xml
"
) );
5
:
6
: container.AddComponent(
"
newsletter
"
,
7
:
typeof
(INewsletterService),
typeof
(SimpleNewsletterService) );
8
: container.AddComponent(
"
smtpemailsender
"
,
9
:
typeof
(IEmailSender),
typeof
(SmtpEmailSender) );
10
: container.AddComponent(
"
templateengine
"
,
11
:
typeof
(ITemplateEngine),
typeof
(NVelocityTemplateEngine) );
12
:
13
: String[] friendsList
=
new
String[]
{
"
john
"
,
"
steve
"
,
"
david
"
}
;
14
:
15
:
//
Ok, start the show
16
:
17
: INewsletterService service
=
18
: (INewsletterService) container[
"
newsletter
"
];
19
: service.Dispatch(
"
hammett at gmail dot com
"
,
20
: friendsList,
"
merryxmas
"
);
21
: }
不断向容器中加入各种类型的对象,加入过程中容器自动建立起它们之间的依赖关系,最后当我们从容器取出对象的时候,就是已经配置好依赖关系的对象。以上就是Castle的工作模式,不过Castle中的配置过程过于透明,在你完全意料不到的情况下,对象的依赖关系就按照对象被注入容器的先后顺序被设定了。非常的自动,非常的透明带来的就是某些时候的莫名奇妙。
再来看看ObjectBuild的实现方式,首先你需要通过属性(Attibute)或者配置文件的方式显式的设定依赖关系:
42
:
public
class
SimpleNewsletterService : INewsletterService
43
:
{
44
:
private
IEmailSender _sender;
45
:
private
ITemplateEngine _templateEngine;
46
:
47
:
public
SimpleNewsletterService(
48
: [Dependency(CreateType
=
typeof
(SmtpEmailSender))]
49
: IEmailSender sender,
50
: [Dependency(CreateType
=
typeof
(NVelocityTemplateEngine))]
51
: ITemplateEngine templateEngine)
52
:
{
53
: _sender
=
sender;
54
: _templateEngine
=
templateEngine;
55
: }
56
:
57
:
public
void
Dispatch(String from, String[] targets, String message)
58
:
{
59
: String msg
=
_templateEngine.Process(message);
60
:
61
:
foreach
(String target
in
targets)
62
:
{
63
: _sender.Send(from, target, msg);
64
: }
65
: }
66
:
67
: }
然后再利用Build直接的构造出对象
public
static
void
Main(
string
[] args)
{
string
config
=
string
.Format(
@"
<object-builder-config xmlns='pag-object-builder'>
<build-rules>
<build-rule type='{0}' mode='Singleton'>
<mapped-type type='{1}'/>
<constructor-params>
<value-param type='System.String'>localhost</value-param>
<value-param type='System.Int32'>110</value-param>
</constructor-params>
</build-rule>
</build-rules>
</object-builder-config>
"
, FullNameIEmailSender, FullNameSmtpEmailSender);
Builder builder
=
new
Builder(ObjectBuilderXmlConfig.FromXml(config));
Locator locator
=
CreateLocator();
INewsletterService newsletterService
=
builder.BuildUp
<
SimpleNewsletterService
>
(locator,
null
,
null
);
String[] friendsList
=
new
String[]
{
"
john
"
,
"
steve
"
,
"
david
"
}
;
//
Ok, start the show
newsletterService.Dispatch(
"
hammett at gmail dot com
"
,
friendsList,
"
merryxmas
"
);
}
从以上我们可以看出
1
. ObjectBuild和Sping类似,需要显式指定依赖关系,不过多出通过Attribute来指定的方式,而Castle则依赖于特定的对象注入顺序。可以说各有优缺点,但是我prefer前者,安全第一。(Castle也提供了在配置文件中显式指定的方式。)
2
. ObjectBuild支持直接创建临时对象,而不注入容器。(注意在上面的代码中我们仅仅BuildUp了SimpleNewsletterService,而没有象Castle那样还要将SimpleNewsletterService所依赖的对象也注入容器。)其实在OB中你可以选择是否将对象注入容器,通常情况下Singleton类型的对象才被注入容器。
3
. 相对与Castle容器的概念,ObjectBuild如同它的名字所示,更象是一个构建器,你可以通过它来构建任意的对象,这些对象可能会被注入容器,也可能仅仅是一个临时对象,不过在对象的创建过程中你可以加入很多的控制,让它更符合你的需求。
4
. 相对而言Castle Ioc的使用更加简洁,而ObjectBuild更加复杂一些(其实比较它们构建对象所需要的语句,OB需要的更少,只是OB的API还不够简洁,需要再做些包装),不过ObjectBuild的定制扩展能力也是相当强大,比如以上通过配置文件和属性(Attribute)结合的配置方式,完全可以通过OB中提供的API搞定,下面就是采用全编程方式的实现:
public
static
void
Main()
{
Builder builder
=
new
Builder();
Locator locator
=
CreateLocator();
builder.Policies.SetDefault
<
ISingletonPolicy
>
(
new
SingletonPolicy(
true
));
ConstructorPolicy policy
=
new
ConstructorPolicy();
policy.AddParameter(
new
ValueParameter
<
string
>
(
"
localhost
"
));
policy.AddParameter(
new
ValueParameter
<
int
>
(
110
));
builder.Policies.Set
<
ICreationPolicy
>
(policy,
typeof
(SmtpEmailSender),
null
);
builder.Policies.Set
<
ITypeMappingPolicy
>
(
new
TypeMappingPolicy(
typeof
(SmtpEmailSender),
null
),
typeof
(IEmailSender),
null
);
builder.Policies.Set
<
ITypeMappingPolicy
>
(
new
TypeMappingPolicy(
typeof
(NVelocityTemplateEngine),
null
),
typeof
(ITemplateEngine),
null
);
ConstructorPolicy policy2
=
new
ConstructorPolicy();
policy2.AddParameter(
new
CreationParameter(
typeof
(IEmailSender)));
policy2.AddParameter(
new
CreationParameter(
typeof
(ITemplateEngine)));
builder.Policies.Set
<
ICreationPolicy
>
(policy2,
typeof
(SimpleNewsletterService),
null
);
INewsletterService newsletterService
=
builder.BuildUp
<
SimpleNewsletterService
>
(locator,
null
,
null
);
String[] friendsList
=
new
String[]
{
"
john
"
,
"
steve
"
,
"
david
"
}
;
//
Ok, start the show
newsletterService.Dispatch(
"
hammett at gmail dot com
"
,
friendsList,
"
merryxmas
"
);
}
5
. Castle Ioc和ObjectBuild都支持属性设值(Property Setter)的注入方式,在此不再举例。
查看全文
相关阅读:
将C#文档注释生成.chm帮助文档
Html5shiv
C#创建COM组件
WebBrowser控件使用详解
iframe跨域
VMware Workstation 虚拟机暂停后无法启动 出现Exception 0xc0000006 (disk error while paging) has occurred.错误
Java Timer 定时器的使用
adf笔记
JS编码解码
【Python】Django CSRF问题
原文地址:https://www.cnblogs.com/tommyli/p/1204074.html
最新文章
tomcat 输入localhost:8080显示404 (找不到tomcat主页)
[1-3] 把时间当做朋友(李笑来)Chapter 3 【提高心智,和时间做朋友】 摘录
表单注册验证
Tomcat几种启动报错及解决办法
Eclipse Xml编译错误Referenced file contains errors
SSH框架阶段 ——SSH的优缺点,使用场景?
[1-2] 把时间当做朋友(李笑来)Chapter 2 【开启自己的心智】 摘录
Java常见分页方式
Maven的镜像设置
Elasticsearch教程(二),IK分词器安装
热门文章
Elasticsearch教程(三),IK分词器安装 (极速版)
Elasticsearch安装(四), elasticsearch head 插件安装和使用。
Elasticsearch教程(五) elasticsearch Mapping的创建
Elasticsearch教程(六) elasticsearch Client创建
Elasticsearch教程(七) elasticsearch Insert 插入数据(Java)
Elasticsearch教程(八) elasticsearch delete 删除数据(Java)
Elasticsearch教程(九) elasticsearch 查询数据 | 分页查询
ElasticSearch Java Api-删除索引
[ElasticSearch]Java API 之 词条查询(Term Level Query)
rtx 导出所有部门和用户
Copyright © 2011-2022 走看看