5.3.2. 자세한 의존과 구성
이전 섹션에서 언급한 바와 같이, 개체 프로퍼티와 생성자 인자는 인라인으로 정의된 값이나 관리되는 다른 개체의 참조를 정의할 수 있다. Spring 의 XML 기반 구성 메타데이터는 <property> 와 <constructor-arg> 엘리먼트 안에 여러 개의 서브 엘리먼트 타입을 지원한다.
5.3.2.1. 직접 값 ( 원시, 문자열, 기타)
<value> 엘리먼트는 사람이 읽을 수 있는 문자열로된 프로퍼티 또는 생성자 인자를 설정한다. 앞에 언급한 바와 같이, TypeConverter 인스턴스는 이런 System.String 타입의 문자열을 실제 프로퍼티나 인자 타입으로 변환한다. Spring.Objects.TypeConverters 네임스페이스의 커스텀 TypeConverter 구현은 .NET BCL 의 기본 TypeConverter 제공된 기능을 강화하여 사용하는 것이다.
다음 예에서, 우리는 BCL 의 System.Data.SqlClient 네임스페이스에 있는 SqlConnection 를 사용한다. 이 클래스는 ConnectionString 프로퍼티를 구성하기 위해 편리한 public 프로퍼티를 제공하며, Spring.NET 개체 팩토리 안에서 사용된다.
<objects xmlns="http://www.springframework.net">
<object id="myConnection" type="System.Data.SqlClient.SqlConnection">
<!-- results in a call to the setter of the ConnectionString property -->
<property name="ConnectionString"
value="Integrated Security=SSPI;database=northwind;server=mySQLServer"/>
</object>
</objects>
5.3.2.1.1. idref 엘리먼트
idref 엘리먼트는 짧고 쉬우며, 컨테이너의 다른 개체의 문자열로 된 id 또는 name 의 에러를 검사하는 방법이다.
<object id="theTargetObject" type="...">
. . .
</object>
<object id="theClientObject" type="...">
<property name="targetName">
<idref object="theTargetObject"/>
</property>
</object>
이것은 런타임 시, 아래의 내용과 동일하다.
<object id="theTargetObject" type="...">
. . .
</object>
<object id="theClientObject" type="...">
<property name="targetName" value="theTargetObject"/>
</object>
두 번째 방법을 선호하는 주된 이유는 idref 를 사용하면, Spring.NET 이 배포시에 다른 개체가 실제로 존재하는지 확인하는 유효성 체크를 하기 때문이다. 두 번째 방법에서 클래스는 프로퍼티 값 targetName 로 자체적으로 유효성을 체크하도록 강제로 의존을 넣었다. 클래스가 컨테이너에 의해 실제로 인스턴스화 될 때, 컨테이너는 아마도 오랜 시간 뒤에 올라오고, 동작할 것이다.
추가적으로, 개체가 실제로 같은 XML 파일을 참조하고 있다면, 개체 이름을 확인하기 위해 XML파서가 구문 분석시에 개체 이름을 확인하기 위해 로컬 어트리뷰트로 사용하는, 개체 식별자를 사용할 것이다.
<property name="targetName">
<idref local="theTargetObject"/>
</property>
5.3.2.1.2. 공백 처리
<value> 엘리먼트의 텍스트에 처음과 끝에 붙는 공백문자는 보통 잘린다. XML 엘리먼트안에 있는 문자열에서 공백문자가 유지되야하는 경우가 있다. 파서는 아래와 같은 xml:space 어트리뷰트를 이해하지 못한다.
<property name="myProp">
<value xml:space="preserve"> 

	</value>
</property>
위 구성은 결과적으로 “\n\r\t” 를 나타낸다. 주의할 점은 명시적으로 ‘xml’ 네임스페이스를 명시하지 않아야 한다는 점이다.
5.3.2.2. 협업하는 개체를 참조하기
ref 엘리먼트는 property 엘리먼트 정의에 들어가는, 가장 마지막 엘리먼트이다. 이것은 컨테이너에서 관리하는, 협업하는 다른 개체를 참조하기 위한 프로퍼티 값을 설정하기위해 사용한다. 이전 예제에서, 프로퍼티 컬렉션을 설정하는 것을 본 것처럼 <ref object> 엘리먼트를 사용하여 협업하는 개체인 SqlConnection 인스턴스를 사용한다. 이전 섹션에서 언급한대로, 개체를 참조한다는 것은 어떤 개체가 프로퍼티에 설정하는지에 의해 의존되고 있다고 생각할 수 있으며, 프로퍼티를 설정하기 전에 필요에 따라 초기화 ( 만약 singleton 개체라면, 컨테이너에 의해 이미 초기화 되었을 수도 있다. ) 될 수 있다. 모든 참조는 결국 다른 개체를 단지 참조하는 것이다. 그러나 다른 개체의 id/name 이 어떻게 정해져 있느냐에 따라, 범위와 유효성 검사를 다루는 3가지 방법이 있다.
대부분의 경우에 ref 엘리먼트의 object 어트리뷰트를 사용하면, 대상 개체를 정할 수 있고 같은 IObjectFactory / IApplicationContext 또는 부모 IObjectFactory / IApplicationContext 내의 ( 같은 XML 파일에 있던 아니던) 어떤 개체들도 참조할 수 있다. object 어트리뷰트의 값은 대상 개체의 id 어트리뷰트와 같거나 대상 개체의 name 어트리뷰트 값 중에 하나이다.
<ref object="someObject"/>
local 어트리뷰트를 사용하여 대상 개체를 정하는 것은, 같은 파일 내에서 id 를 참조하는 ( XML 의 유효성 검사를 하는 ) XML 파서의 능력을 이용한다. local 어트리뷰트의 값은 대상 개체의 id 어트리뷰트와 반드시 같아야 한다. 같은 파일 안에서, 일치하는 엘리먼트를 찾지 못하면 XML 파서는 에러를 발생 시킬 것이다. 대상 개체가 같은 XML 파일에 있는 경우 로컬 형태를 사용하는 것은 최선의 선택이다.
<ref local="someObject"/>
현재의 IObjectFactory ( 또는 IApplicationContext) 의 부모 IObjectFactory ( 또는 IApplicationContext) 안에 생성된 개체를 대상 개체로 참조하기 위해 parent 어트리뷰트를 사용한다. parent 어트리뷰트의 값은 대상 개체의 id 어트리뷰트와 동일하거나 대상 개체의 name 어트리뷰트의 값 중 하나와 같아야 한다. 다양한 개체 참조의 방법 중, 어떤 종류의 프록시와 부모 컨텍스트에 있는 개체를 래핑하거나 원래 개체를 래핑하는 것이 필요할 때 주로 이 방법을 사용한다.
<ref parent="someObject"/>
5.3.2.3. 인라인 개체
property 엘리먼트 안의 object 엘리먼트는 컨테이너 밖에서 정의하는 개체를 참조하는 대신, 인라인 개체 값을 정의하는데 사용된다. 인라인 개체 정의는 id 나 name 이 정의될 필요가 없다. ( 사실, 정의되었다면 무시될것이다. )
<object id="outer" type="...">
<!-- Instead of using a reference to target, just use an inner object -->
<property name="target">
<object type="ExampleApp.Person, ExampleApp">
<property name="name" value="Tony"/>
<property name="age" value="51"/>
</object>
</property>
</object>
5.3.2.4. 컬렉션 값 설정
list, set, name-values, dictionary 엘리먼트는 각각 IList, ISet, NameValueCollection, IDictionary 타입의 인자와 프로퍼티를 사용하여 정의하고 설정할 수 있다.
<objects xmlns="http://www.springframework.net">
<object id="moreComplexObject" type="Example.ComplexObject">
<!--
results in a call to the setter of the SomeList (System.Collections.IList) property
-->
<property name="SomeList">
<list>
<value>a list element followed by a reference</value>
<ref object="myConnection"/>
</list>
</property>
<!--
results in a call to the setter of the SomeDictionary (System.Collections.IDictionary) property
-->
<property name="SomeDictionary">
<dictionary>
<entry key="a string => string entry" value="just some string"/>
<entry key-ref="myKeyObject" value-ref="myConnection"/>
</dictionary>
</property>
<!--
results in a call to the setter of the SomeNameValue (System.Collections.NameValueCollection) property
-->
<property name="SomeNameValue">
<name-values>
<add key="HarryPotter" value="The magic property"/>
<add key="JerrySeinfeld" value="The funny (to Americans) property"/>
</name-values>
</property>
<!--
results in a call to the setter of the SomeSet (Spring.Collections.ISet) property
-->
<property name="someSet">
<set>
<value>just some string</value>
<ref object="myConnection"/>
</set>
</property>
</object>
</objects>
BCL 의 많은 클래스 중, 컬렉션 클래스를 위해 읽기 전용 프로퍼티를 갖는 것이 있다. Spring.NET 팀이 읽기 전용 컬렉션을 봤을 때, 컬렉션 클래스의 참조를 얻기 위해 getter 프로퍼티를 구성하기로 했으며, 컬렉션에 값을 추가하는 기능도 진행하기로 했다. 그 결과로 컬렉션 프로퍼티를 다루는 다음과 같은 방법을 추가했다.
Dictionary 항목의 값이나 값을 설정하는 것은 서로 다른 엘리먼트가 될 수 있다.
(object | ref | idref | expression | list | set | dictionary | name-values | value | null)
컬렉션 프로퍼티를 설정할 때의 값과 참조를 위해, 더 단순화한 형태를 Section 5.3.2.8. Value and ref shortcut forms 에서 볼 수 있다.
[출처] Spring.NET Framework 가이드 문서
[업데이트]
1차 : 2009-07-01 16:20


