2012-06-01 2 views
2

xsd에서 생성 된 클래스 인스턴스를 만드는 일반적인 솔루션을 만들어야합니다. 예를 들면 : 인스턴스 만들기 및 런타임 어셈블리의 속성 할당

<?xml version="1.0" encoding="utf-8"?> 
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <xs:element name="PS"> 
    <xs:complexType> 
     <xs:sequence> 
     <xs:element name="P" maxOccurs="unbounded"> 
      <xs:complexType> 
      <xs:sequence> 
       <xs:element name="FXs" maxOccurs="1" minOccurs="0"> 
       <xs:complexType> 
        <xs:sequence> 
        <xs:element maxOccurs="unbounded" name="FX" minOccurs="1"> 
         <xs:complexType> 
         <xs:attribute name="asOfDate" type="xs:date" use="required" /> 
         <xs:attribute name="currency" type="xs:string" use="required" /> 
         <xs:attribute name="rate" type="xs:decimal" use="required" /> 
         </xs:complexType> 
        </xs:element> 
        </xs:sequence> 
       </xs:complexType> 
       </xs:element> 
</xs:sequence> 
      <xs:attribute name="PName" type="xs:string" /> 
      <xs:attribute name="currency" type="xs:string" /> 
      </xs:complexType> 
     </xs:element> 
     </xs:sequence> 
    </xs:complexType> 
    </xs:element> 
</xs:schema> 

나는 그것이 클래스 PS, PSP 및 PSFX있을 것이다이 XSD 런타임에서 어셈블리를 생성

. 이 경우 속성과 예상되는 것을 알고 있으므로 createinstance와 getproperties 및 setvalue가 작동합니다. 나는 포트폴리오가 Portfolio 포트폴리오의 배열을 가질 것이라는 것을 안다.

case "PS": 
            if (p== null) 
             p= myAssembly.CreateInstance(cls.FullName); 
            break; 

           case "PSP": 
            myClass = myAssembly.CreateInstance(cls.FullName); 
            myClass.GetType().GetProperty("PName").SetValue(myClass, dt.Rows[0]["PortfolioName"].ToString(), null); 
            myClass.GetType().GetProperty("currency").SetValue(myClass, dt.Rows[0]["Currency"].ToString(), null); 
            if (myClasses == null) 
             myClasses = Array.CreateInstance(myClass.GetType(), deals.Count()); 
            myClasses.SetValue(myClass, l); 
            l++; 
            portfolio.GetType().GetProperty("P").SetValue(p, myClasses, null); 

지금 나는 어떤 XSD을 (단지 위)과 어셈블리를 생성 할 수 있습니다에서 일반적인 솔루션을 갖고 싶어. 이미 어셈블리를 생성했지만 지금은 내 질문에 동적으로 거기에 어떤 속성이 있는지 모르는 클래스 속성을 할당합니까? 제 말은 일반 솔루션을 만들 때 클래스가 다른 클래스의 객체 목록을 사용한다는 것을 어떻게 알 수 있습니까? 그래서 classnames와 propertynames를 하드 코딩하는 대신에 인스턴스와 속성을 얻을 수있는 방법이 있습니다. 위의 스 니펫에서 볼 수 있듯이 데이터 세트의 값을 속성에 할당하고 있습니다. 데이터베이스의 값을 columnname, attributename 및 parentnode로 저장하는 것이 계획입니다. P 노드의 PName 속성은 열 이름 Pname에서옵니다. 내 코드에 하드 코드가 없도록 디자인을 원합니다. 몇 가지 예 또는 디자인 아이디어를 제안 해주십시오.

죄송합니다. 제발 나와 함께 감옥에 보내주십시오. 제 의견이 맞지 않으면 알려주세요.

답변

0

XML을 구문 분석하고 어셈블리를 만들지 않는 것이 더 쉬울까요? XmlSchema 및 해당 하위 개체를 사용하여 데이터베이스에서 원하는 모든 정보를 추출 할 수 있습니다. XML 출력을 조작하기 위해 XML 문서를 처리하기위한 일반 프레임 워크를 사용할 수 있습니다. 또는 어셈블리가 실제로 필요한 경우 먼저 XML을 변경 한 다음이를 객체로 직렬화 해제 할 수 있습니다.

그러나 클라이언트 코드가 컴파일 타임에 어셈블리의 CLR 형식을 알지 못하는 경우 어셈블리를 만드는 것이 처음부터별로 의미가 없으므로 코드를 만드는 것이 더 낫다고 생각합니다. 필요한 경우 XML 또는 데이터베이스 열로 변환 할 수있는 일반 중간 데이터 형식.

I. 첫째, 작은 자격 :

1

긴 질문은 긴 답변을받을 권리가 나는 잠시 동안 클래스/어셈블리를 생성 작업을했습니다. 실제로 CodeDom (선호하는 방법) 또는 IL Emit을 사용하여이 작업을 수행 할 수 있습니다. 그러나 아마해서는 안됩니다.

  • 첫 번째 인수는 XML 모델이 그렇게 유용하지 않다는 것입니다. 좋아, 그래서 당신은 클래스로 바꾸고 싶은 XML이있다. 그렇게하기 위해 어떻게 든 XML을 코드 (C# 또는 VB 또는 심지어 IL)로 변환 한 다음 런타임에 컴파일하여 동적 클래스를 만듭니다. 그렇다면 XML 대신 직접 코드를 사용하는 것이 어떻습니까?
  • 위의 요점은 결과가 나왔습니다. 디자인 타임에 클래스를 지정하는 경우 클래스를 컴파일하지 않는 이유는 무엇입니까? (따라서 컴파일 타임에 생성합니까?)

    II

. 귀하의 디자인 드라이버는 하드 코드이 아닙니다.

  • 먼저 철학적 분석 : 당신이 하드 코드 역설이다 코드를 원하지 않는다.
  • 소스에서 하드 코딩 된 문자열을 최소화하는 것이 좋습니다. 그 이유는 (1) 문자열이 변경 될 것으로 예상되기 때문에 (2) 테스트가 더 쉬워 질 수 있기 때문입니다.
    • 당신은 하드 코드를 피해야한다 문자열,하지 프로그램 구조에만해야
    • 구성 변화가 예상되는 것들 ("동적") 또는 알 수없는 당신에게 : 우리는이 정의에서 두 가지를 추출 할 수 있습니다 컴파일 타임에. 데이터베이스 구조는 거의 불가능합니다.

지금, 당신은 하드 코드를 방지 할 수 있습니다, 추상적으로 생각? 귀하의 예제에서 당신은 이미 처리하려는 XML 파일의 데이터를 참조하는 일부 문자열을 사용했습니다. 처리하려는 데이터에 대한 정보없이 프로그램이 어떻게 작동합니까?

은 (네하는 응답이)

...

답변 : 당신은 단지 데이터를 표시하는 경우, 즉, 전체 데이터 구조가 프로그램 로직 관련이 없습니다. 예를 들면 텍스트 편집기입니다. 텍스트 편집기는 사전에 데이터를 알 필요가 없습니다. 파일에있는 그대로 렌더링합니다.

그러나 귀하의 경우 데이터베이스는 데이터의 "마스터"입니다. 그것은 당신의 프로그램에서 그것을 분리하려고 아무 소용이 없다.