2013-02-14 2 views
0

방금 ​​C#의 저장소 패턴에 대해 읽었습니다. 실제 데이터에 액세스하는 방법에 대해 상호 교환 가능한 계층을 제공합니다. 훌륭합니다. 그러나 다음을 고려하십시오.교환 가능한 데이터 액세스가있는 저장소 패턴

XML 데이터를 파일에서 가져 와서 C# 개체 (Person.cs POCO)로 반환하는 XmlPersonRepository가 있습니다. 이제는 XML 데이터의 물리적 인 소스를 교환 할 수 있기를 바랍니다. 원래는 파일에서 가져 왔지만 웹 서버 나 리소스 문자열에서 가져올 수도 있습니다. 어떻게 이것을 가장 재사용 가능한 방법으로 구현할 수 있습니까? 코드 중복을 의미하기 때문에 XmlPersonFromFileRepository 및 XmlPersonFromWebRepository와 같은 것을 쓰고 싶지 않습니다. 원시 XML 데이터를 C# 객체로 변환하는 코드를 복제하지만 파일이나 웹 서비스에서 XML을 가져온 경우에도이 코드는 그대로 유지됩니다. 두 클래스 모두에서 전환 코드를 사용하는 것은 불필요합니다.

간단히 말해서, 나는 두 소스의 추상적인 XML 데이터를 가져 오는 하나의 레이어와이 데이터를 C# 객체로 변환하는 또 다른 레이어가 필요합니다. 둘 다 상호 교환 가능해야합니다.

어떻게 구현할 수 있습니까? 그리고 이것이 좋은 생각인지 아닌지 나에게 말해줘, 나는 바른 길을 가고 있니?

+0

DEpendency injection은 당신의 친구입니다 !! – DarthVader

+0

감사합니다. 도움이 되겠습니다. –

답변

1

Simple. 귀하는 귀하의 질문에 방금 말씀하셨습니다.

당신은 해결하기 위해 두 가지 문제가 있습니다

  • 가 소스에서 C#을 개체에
  • 변환 XML 데이터를 XML 데이터를 가져

첫 번째 문제 구현하려면 : - IXmlDataGetter, 인터페이스를 원본에서 단일 XML 데이터 가져 오기



    public interface IXmlDataGetter { 
     XmlData GetData(XmlDataName name); 
    } 

"XMLDATA"이어야 어느 바이트 [] 또는 스트림 (XML 데이터의 인코딩에 관련하여 메타 데이터를 포함하기 때문에, I 그것이 바이트 레벨로 유지되어야한다고 생각) 또는 (a DOM 트리 일 등 XmlNode). 자신에게 가장 적합한 솔루션을 선택하십시오.

"XmlDataName"은 저장된 데이터를 식별하는 방법입니다. 데이터에는 이름이 있지만 복잡 할 수 있습니다. 그것은 단지 "PERSON"문자열 일 수도 있고, ID 인 정수 25 일 수도 있습니다. ID가 25 인 사람의 데이터 이름은 쌍 ("PERSON", 25) 일 수 있습니다.

이 인터페이스는, DB 구현 될 수



    public class DBXmlDataGetter : IXmlDataGetter { 
     XmlData GetData(XmlDataName name) { 
     return ResultOfQuery("SELECT xml_text FROM " + name.first /* PERSON */ + " WHERE ID=" + name.second /* 25 */); 
     } 
    } 

이 인터페이스는 또한 파일 구현 될 수

:

물론 "ResultOfQuery"와 "ContentsOfFile"의


    public class FileXmlDataGetter : IXmlDataGetter { 
     XmlData GetData(XmlDataName name) { 
     return ContentsOfFile(name.first /* PERSON */ + "_" + name.second /* 25 */ + ".xml"); 
     } 
    } 

는 단지 이름입니다 내가 해결하도록 남겨 두는 것들. 웹의 경우 동일한 방식으로 XmlDataName에서 URL을 작성하십시오.

지금. 두 번째 문제는 XML을 C# 객체로 변환하는 것입니다. XMLDeserializer를 사용하거나 XMLReader로 데이터를 구문 분석하고 명시 적으로 객체를 빌드 할 수 있습니다. 당신은 테 작업을 수행하고 생성자 매개 변수로 적절한 전략을 취 클래스를 만들 수 있습니다



    public class XmlPersonRepository { 
     private readonly IXmlDataGetter _getter; 

     public PersonFetcher(IXmlDataGetter getter) { 
     _getter = getter; 
     } 

     Person GetFromId(int id) { 
     var xmlData = _getter.GetData(new XmlDataName("PERSON", id)); 
     return ConvertToPerson(xmlData); 
     } 
    } 

여기 IOC의/의존성 주입의 철학적 질문에받지 않습니다, 그러나 이것은 기본 패턴입니다

. 변환을 수행하는 클래스는 변환 만 수행합니다. 끝에서 끝까지 유스 케이스를 수행하는 데 필요한 것은 위에서 "주입"됩니다.

당신은 책임을 분리 했으므로 원하는 경우 XML 데이터를 사용자 복사/붙여 넣기에서 텍스트 상자로 가져올 수 있습니다.

+0

이 위대하고 이해하기 쉬운 예제에 감사드립니다. 나는 이미 의존성 주입에 대해 읽기 시작했다. 좋은데, 실제로 두 단계 (1. 원시 데이터 얻기, 2. 데이터 변환)에 대한 책임을 실제로 분할하는 방법에 대한 나의 초기 질문을 해결하지 못한다고 생각한다. 코드 예제를 제공합니다. 굉장해, 다시금 고마워! –

+0

이것은 하나의 예일 뿐이지 만 질문을 다시 읽는다면 완전히 대답하지 않습니다. BOTH를 상호 교환 가능하게하려면 "ConvertToPerson"메서드를 단일 메서드로 IXmlToPersonConverter 인터페이스로 추상화 한 다음 생성자에 주입해야합니다. –

0

마찬가지로 Dependency Injection/Ioc이 무엇인지 확인하고 (Ninject, Autofac 등) 일부 프레임 워크를 살펴보십시오. IXmlPersonRepository :

  • XmlDBPersonRepository IXmlPersonRepository : 간단히 말해서 당신은

    • XmlFilePersonRepository처럼 당신에게 XML을 제공 할 것입니다 모든 다른 클래스에 구현 다음 방법을 정의하는 인터페이스 IXmlPersonRepository을 만들고해야

      등등.

      그런 다음 IXmlPersonRepository 인터페이스를 사용하여 전화를 겁니다. DI 비트는 인터페이스의 구체적인 구현을 담당하며 db, 파일 등간에 쉽게 바꿀 수 있습니다.

  • +0

    감사합니다. 종속성 주사를 확인해 보겠습니다. 또한 IXmlPersonRepository에 관한 힌트를 주셔서 감사합니다. –