Inside ObjectBuilder Part 4

news/2024/7/6 0:59:41

 

ObjectBuilderApplicationBlock

/黄忠成

2006/9/21

 

八、ObjectBuilder实务

 

8-1ObjectBuilderWithConfiguration

截至目前为止,本文一直以程序方式来配置ObjectBuidler建立对象所需的各种对象,但在实务上,这些动作应该是交由配置文件来负责,这样才能在不重新编译应用程序的情况下,改变其行为或增加其功能。很幸运的,MicrosoftObjectBuilder的范例中提供了一个途径来达到此目的,该范例定义了一个.xsd文件,其内定义了ConstructorInjectionSetterInjectionSingletonTypeMapping所需要的schema,当然!这个xsd中也定义了Strategyschema,允许设计者通过配置文件来添加对象建立时所需使用的Strategys

 

ConsturctorInjectionWithConfiguration

我将Microsoft所提供可配置ObjectBuidler的范例中关于处理配置文件时的.xsd及相关文件提取出来,并添加MethodInjection时所需要的schema及程序代码,放置于本文的范例程序档中,当读者们需要使用配置文件这个功能时,可以将Config目录中的ObjectBuilderXmlConfig.xsdObjectBuilderXmlConfig.xsxObjectBuilderXmlConfig.csObjectBuilderXmlConfig.Generate.cs等文件复制到项目目录中,并将ObjectBuilderXmlConfig.xsdObjectBuilderXmlConfig.Generate.cs加入到项目中,完成后再将ObjectBuilderXmlConfig.xsd设置成EmbeddedResource,如图10所示。

10

接着将修改ObjectBuilderXmlConfig.cs中关于由Resource中取得.xsd内容的程序代码,修正namespace为项目的默认namespace即可。

程序44

privatestaticObjectBuilderXmlConfigParseXmlConfiguration(stringconfig)

{

XmlSerializerser=newXmlSerializer(typeof(ObjectBuilderXmlConfig));

StringReaderstringReader=newStringReader(config);

XmlSchemaschema=

XmlSchema.Read(

Assembly.GetExecutingAssembly().GetManifestResourceStream(

"OB_CSConfigurationTest.ObjectBuilderXmlConfig.xsd"),null);

XmlReaderSettingssettings=newXmlReaderSettings();

settings.ValidationType=ValidationType.Schema;

settings.Schemas.Add(schema);

XmlReaderreader=XmlReader.Create(stringReader,settings);

ObjectBuilderXmlConfigconfigData=(ObjectBuilderXmlConfig)ser.Deserialize(reader);

returnconfigData;

}

 

要使用配置文件来完成ConstructorInjection,我们必须在项目中新增一个xml文件,内容如下所示。

 

<object-builder-configxmlns="pag-object-builder">

<build-rules>

<build-rule

type="OB_ConfigurationTest.InputAccept,OB_CSConfigurationTest"mode="Instance">

<constructor-params>

<ref-param

type="OB_ConfigurationTest.PromptDataProcessor,OB_CSConfigurationTest"/>

constructor-params>

build-rule>

build-rules>

object-builder-config>

 

ObjectBuilderXmlConfig.xsd定义中,build-rules代表着此BuilderContext中所有的对象建立规则,每个build-rule对应着一个“类型/id”,类型格式为 id部份则可通过添加name这个attribute来设置,未指定时就以null为默认值,如下。

 

<build-rule

type="OB_ConfigurationTest.InputAccept,OB_CSConfigurationTest"

name=”id 1” mode="Instance">

 

每个build-rule可以拥有一个constructor-params区段,设计者可以在这个区段中添加value-param或是ref-param定义,前者是直接设置该参数的值,后者是通过reference方式来设值,本例中是将InputAccept建构子的第一个参数值指定为PromptDataProcessor。程序45是使用这个配置文件的程序列表。

 

程序45

usingSystem;

usingSystem.Collections.Generic;

usingSystem.Text;

usingSystem.IO;

usingSystem.Configuration;

usingMicrosoft.Practices.ObjectBuilder;

usingMicrosoft.Practices.EnterpriseLibrary.Common.Configuration.ObjectBuilder;

usingMicrosoft.Practices.EnterpriseLibrary.Common.Configuration;

 

namespaceOB_ConfigurationTest

{

classProgram

{

staticvoidMain(string[]args)

{

using(FileStreamfs=newFileStream("XmlFile1.xml",FileMode.Open,FileAccess.Read))

{

using(StreamReadersr=newStreamReader(fs))

{

Builderbuilder=newBuilder(ObjectBuilderXmlConfig.FromXml(sr.ReadToEnd()));

InputAcceptaccept=builder.BuildUp<InputAccept>(newLocator(),null,null);

accept.Execute();

Console.Read();

}

}

}

}

 

publicclassInputAccept

{

privateIDataProcessor_dataProcessor;

 

publicvoidExecute()

{

Console.Write("PleaseInputsomewords:");

stringinput=Console.ReadLine();

input=_dataProcessor.ProcessData(input);

Console.WriteLine(input);

}

 

publicInputAccept([Dependency(Name="dataProcessor")]IDataProcessordataProcessor)

{

_dataProcessor=dataProcessor;

}

}

 

publicinterfaceIDataProcessor

{

stringProcessData(stringinput);

}

 

publicclassDummyDataProcessor:IDataProcessor

{

 

#regionIDataProcessorMembers

 

publicstringProcessData(stringinput)

{

returninput;

}

 

#endregion

}

 

publicclassPromptDataProcessor:IDataProcessor

{

#regionIDataProcessorMembers

 

publicstringProcessData(stringinput)

{

return"yourinputis:"+input;

}

 

#endregion

}

}

 

SetterInjectionWithConfiguration

 

同样的,我们也可以通过配置文件来完成SetterInjection,此范例所使用的配置文件如下。

 

<object-builder-configxmlns="pag-object-builder">

<build-rules>

<build-rule

type="OB_CSPropertyInjectionTest.InputAccept,OB_CSPropertyInjectionTest"mode="Instance">

<propertyname="DataProcessor">

<ref-param

type="OB_CSPropertyInjectionTest.PromptDataProcessor,OB_CSPropertyInjectionTest"/>

property>

build-rule>

build-rules>

object-builder-config>

 

设计者必须将要设置的属性定义放置于build-rule区段中的propertyproperty有一个nameattribute,代表着欲设置属性的名称,如要设置一个以上的属性,只需添加多个property区段即可,程序46是使用此配置文件的程序代码。

 

程序46

usingSystem;

usingSystem.Collections.Generic;

usingSystem.Text;

usingSystem.IO;

usingSystem.Configuration;

usingMicrosoft.Practices.ObjectBuilder;

usingMicrosoft.Practices.EnterpriseLibrary.Common.Configuration.ObjectBuilder;

usingMicrosoft.Practices.EnterpriseLibrary.Common.Configuration;

 

namespaceOB_CSPropertyInjectionTest

{

classProgram

{

staticvoidMain(string[]args)

{

using(FileStreamfs=newFileStream("XmlFile1.xml",FileMode.Open,FileAccess.Read))

{

using(StreamReadersr=newStreamReader(fs))

{

Builderbuilder=newBuilder(ObjectBuilderXmlConfig.FromXml(sr.ReadToEnd()));

InputAcceptaccept=builder.BuildUp<InputAccept>(newLocator(),null,null);

accept.Execute();

Console.Read();

}

}

}

}

 

publicclassInputAccept

{

privateIDataProcessor_dataProcessor;

 

[Dependency(Name="DataProcessor")]

publicIDataProcessorDataProcessor

{

get

{

return_dataProcessor;

}

set

{

_dataProcessor=value;

}

}

 

publicvoidExecute()

{

Console.Write("PleaseInputsomewords:");

stringinput=Console.ReadLine();

input=_dataProcessor.ProcessData(input);

Console.WriteLine(input);

}

}

 

publicinterfaceIDataProcessor

{

stringProcessData(stringinput);

}

 

publicclassDummyDataProcessor:IDataProcessor

{

 

#regionIDataProcessorMembers

 

publicstringProcessData(stringinput)

{

returninput;

}

 

#endregion

}

 

publicclassPromptDataProcessor:IDataProcessor

{

#regionIDataProcessorMembers

 

publicstringProcessData(stringinput)

{

return"yourinputis:"+input;

}

 

#endregion

}

}

 

MethodInjectionWithConfiguration

 

Microsoft所提供的配置文件机制并未定义MethodInjection的功能,我将其稍微修改来支援此功能,下面是MethodInjection时所用的配置文件。

 

<object-builder-configxmlns="pag-object-builder">

<build-rules>

<build-rule

type="OB_CSMethodInjectionTest.InputAccept,OB_CSMethodInjectionTest"mode="Instance">

<methodname="SetDataProcessor">

<ref-param

type="OB_CSMethodInjectionTest.PromptDataProcessor,OB_CSMethodInjectionTest"/>

method>

build-rule>

build-rules>

object-builder-config>

 

用法与property大致相同,程序47是程序代码列表。

 

程序47

usingSystem;

usingSystem.Collections.Generic;

usingSystem.Text;

usingSystem.IO;

usingMicrosoft.Practices.ObjectBuilder;

 

namespaceOB_CSMethodInjectionTest

{

classProgram

{

staticvoidMain(string[]args)

{

using(FileStreamfs=newFileStream("XmlFile1.xml",FileMode.Open,FileAccess.Read))

{

using(StreamReadersr=newStreamReader(fs))

{

Builderbuilder=newBuilder(ObjectBuilderXmlConfig.FromXml(sr.ReadToEnd()));

InputAcceptaccept=builder.BuildUp<InputAccept>(newLocator(),null,null);

accept.Execute();

Console.Read();

}

}

}

}

 

publicclassInputAccept

{

privateIDataProcessor_dataProcessor;

 

publicvoidSetDataProcessor([Dependency(Name="dataProcessor")]IDataProcessordataProcessor)

{

_dataProcessor=dataProcessor;

}

 

publicvoidExecute()

{

Console.Write("PleaseInputsomewords:");

stringinput=Console.ReadLine();

input=_dataProcessor.ProcessData(input);

Console.WriteLine(input);

}

}

 

publicinterfaceIDataProcessor

{

stringProcessData(stringinput);

}

 

publicclassDummyDataProcessor:IDataProcessor

{

 

#regionIDataProcessorMembers

 

publicstringProcessData(stringinput)

{

returninput;

}

 

#endregion

}

 

publicclassPromptDataProcessor:IDataProcessor

{

#regionIDataProcessorMembers

 

publicstringProcessData(stringinput)

{

return"yourinputis:"+input;

}

 

#endregion

}

}

 

SingletonWithConfiguration

 

通过配置文件,也可以定义那个“类型/id”的对象是使用Singleton模式,如下所示。

 

<build-ruletype="OB_CSMethodInjectionTest.PromptDataProcessor,OB_CSMethodInjectionTest"mode="Singleton"/>

 

TypeMappingWithConfiguration

 

我们也可以在配置文件中定义TypeMapping,如下所示。

 

<build-rule

type="OB_CSMethodInjectionTest.IDataProcessor,OB_CSMethodInjectionTest"mode="Instance">

<mapped-type

type="OB_CSMethodInjectionTest.PromptDataProcessor,OB_CSMethodInjectionTest"/>

build-rule>

 

CustomizeStrategys

 

通过配置文件,也可以定义建立对象时所需要的Strategys,如下所示。

 

<object-builder-configxmlns="pag-object-builder">

<strategiesinclude-default="false">

<strategy

type="Microsoft.Practices.ObjectBuilder.TypeMappingStrategy,Microsoft.Practices.ObjectBuilder"/>

<strategy

type="Microsoft.Practices.ObjectBuilder.CreationStrategy,Microsoft.Practices.ObjectBuilder"/>

<strategy

type="Microsoft.Practices.ObjectBuilder.MethodExecutionStrategy,Microsoft.Practices.ObjectBuilder"/>

.......................

object-builder-config>

 

include-default属性决定是否包含Builder对象所内建的Strategys

 

九、后记

ObjectBuilder是一个相当不错的DependencyInjection实作体,虽然相对于SpringAvalonObjectBuilder并不是相当的完整,例如没有完整的配置文件驱动特色,但她所具备的高度延展性,可以让我们轻易的达到这个需求,且日后相信ObjectBuilder也会内建这些功能的。





http://www.niftyadmin.cn/n/3658117.html

相关文章

Towards Precise Supervision of Feature Super-Resolution for Small Object Detection 阅读笔记

Better to Follow, Follow to Be Better: Towards Precise Supervision of Feature Super-Resolution for Small Object Detection 文章针对2阶段的detection提出了一种对小面积ROI的feature进行SR的方法&#xff0c;并提出了对该SR进行监督的机制首先是发现问题&#xff0c;问…

Inside ObjectBuilder 范例

Object Builder Application Block文/黃忠成2006/9/21一、IoC 简介IoC 的全名是“Inversion of Control”&#xff0c;字面上的意思是“控制反转”&#xff0c;要了解这个名词的真正含义&#xff0c;得从“控制”这个词切入。一般來说&#xff0c;当程序员撰写一个Console 程序…

数电学习笔记(1)

diode 二极管PMOS低电平导通&#xff0c;NMOS高电平导通输出特性要掌握HPRI/BNI是high priority &#xff0c;binary&#xff0c;高位优先二进制编码器的意思&#xff0c;代表为8线-3线优先编码器 74148HPRI/BCD 表示BCD编码器&#xff0c;代表为10线-4线优先编码器 7414774138…

Asp.net 2.0 自定义控件开发[创建自定义右键PopupMenu控件][示例代码下载]

(一). 概述1. 当鼠标悬浮到控件对象上, 右击, 会弹出此自定义控件.2. 仅当控件支持oncontextmenu事件. 另外, 与其功能类似的控件[浮动Toobar自定义控件](二). 运行如图(三). 用法1. 将PopupTraceMenur控件Dll添加引用到Web站点工程中2. 从工具箱拖动一个PopupTraceMenu控件和另…

根据分割图生成bbox的csv标注:

根据分割图生成bbox的csv标注&#xff1a; import numpy as np import skimage from skimage.measure import label,regionprops from skimage.filters import roberts import os import cv2 import pandas as pddef get_patch_csv(filename_list, root_dir, output_path, are…

Asp.net 2.0 自定义控件开发[创建自定义浮动菜单FloadMenu控件][示例代码下载]

(一). 概述1. 当鼠标悬浮到控件对象上, 会弹出此自定义控件.2. 具有通用性, 只要支持 onmouseenter/onmouseleave 等几个事件方法的目标控件都可以使用此控件.3. 此控件与前面自定义控件[右击弹出菜单]控件有些类似, 区别是这个控件客户端JavaScript部分有些麻烦.(二). 运行如…

Asp.net 2.0 自定义控件开发[实现GridView多行表头固定表体滚动效果][示例代码下载]

(一). 概述1. 实现GridView表头固定表体滚动效果2. 继承GridView的所有功能, 增加扩展功能, 表体滚动功能; 不需要另外加辅助滚动控件, 如.3. 支持多行表头滚动, 此控件能够自动检测到使用者增加的表头的行数. 准确的实现表头滚动.有增加GridView多表头实现方案, 请看[多表头自…

Asp.net 2.0 自定义控件开发[实现自动计算功能(AutoComputeControl)][示例代码下载]

(一). 概述 业余时间做了一个非常有用的控件, 介绍一下. 一般当我们要实现这样一个计算功能页面: TextBox1(单价) * TextBox2(数量) TextBox3(总和); 并且当在TextBox1或TextBox2中输入数据, 鼠标离开时, TextBox3控件能够即时重…