2011-02-24 9 views
0

이라는 클래스를 작성 중이며이 클래스에는 외부 리소스에서 XML 데이터를 가져 오는 두 가지 정적 메서드가 있습니다. 아래의 예에서는 매우 유사하기 때문에 하나만 보여 드리겠습니다.이 XDocument 코드는 안전한가요?

내가 알아 내려고하는 것은이 코드가 유효하지 않은 URL, 유효하지 않은 데이터 등의 측면에서 "안전"한 것인지 여부입니다. 기본적으로 더 강력합니다. 여기 TEH 코드

private static string XmlUri 
    { 
     get { return "path-to-xml-file"; } 
    } 
private static XDocument XmlFile { get; set; } 
public int ID { get; set; } 
public string Name { get; set; } 
public int Parent { get; set; } 

/// <summary> 
/// Gets a specific category 
/// </summary> 
/// <param name="id"></param> 
/// <returns>A Category with the specified ID</returns> 
public static Category Get(int id) 
{ 
    try 
    { 
     if (XmlFile == null) 
      XmlFile = XDocument.Load(XmlUri); 
    } 
    // Invalid URL or data 
    catch (Exception ex) 
    { 

     // TODO: Log exception 
     Console.WriteLine(ex.Message); 
    } 

    if (XmlFile == null) 
     return null; 

    var cat = from category in XmlFile.Descendants("Category") 
       where category.Attribute("id").Value.ParseSafe() == id 
       select new Category 
       { 
        ID = category.Attribute("id").Value.ParseSafe(), 
        Parent = category.Attribute("parent").Value.ParseSafe(), 
        Name = category.Value 
       }; 

    return cat.SingleOrDefault(); 
} 
+1

외부 XML을 얼마나 제어합니까? 스키마에 대해 유효성을 검사하려고 할 수 있습니다. 또한 여러 스레드가 XML을 읽으려고 할 때 코드가 폭발 할 수도 있습니다 (기술 용어를 사용하려면 ...). – ChaosPandion

+0

@Chaos - XML ​​파일을 제어 할 수 없으므로 내가 갖고있는 것과 작업해야합니다. thread-safety 부분에 대해 좀 더 설명해 주시겠습니까? 그 시나리오를 실행 해보고 싶지만 확신하고 싶지는 않습니다. 감사! – Marko

답변

1

정의 '안전'입니다. 무언가 잘못되었을 때 코드에서 null을 생성합니다. 나는 XDocument.Load() 후에 catch 블록에 (다시) 던지기를 고려할 것이다. 에 있지 않으려면이 아니라 잘못된 URL을 무시하십시오.

그리고 ParseSafe() 및 SingleOrDefault도 문제가됩니다. id이 누락되었거나 잘못 형성된 경우 어떻게 하시겠습니까?

작은 개선 : XmlFile의 getter에 Load-on-Demand 로직을 넣을 수 있습니다. 카테고리 옆에있는 다른 요소를 원할 경우 쉽게 만듭니다.

+0

+1 : "return null"behafior에 대해. 발신자가 기대하지 않을 수 있습니다. –

+0

감사합니다. @Henk, 오류가 발생했을 때 null을 반환하며,이 클래스를 사용할 응용 프로그램의 다른 부분은 다른 작업을 수행하기 전에 null을 검사합니다. ParseSafe 메서드는 int.TryParse를 사용하여 정수를 반환하는 문자열 확장이며 유효하지 않은 경우 0을 반환합니다. 나는 실제로 목표로하고있는 일치 항목이 없다면 SingleOrDefault가 null을 반환 할 것으로 추정한다. 로드 온 디맨드 로직에 관해서는 이와 비슷한 것을 의미 했습니까? 'private XDocument XmlFile {get {return XDocument.Load (XmlUri);}}' – Marko

+0

호출자가 "결과 없음"과 "제공자 폭발"의 차이를 신경 쓰지 않는다면 괜찮습니다. 그리고 getter 안에'if x! = null'을 의미했습니다. –

1

언급 된 ChaosPandion만큼 안전하지 않습니다.

혼란스러운 성능 동작 - Get (int)은 간단한 빠른 방법처럼 보이지만 실제로는 중요한 작업을 포함하지 않습니다. 게으른 초기화를 사용하고 사전에 범주 onece의 전체 모음을 읽습니다.

예외를 잡아서 삼키지 않아야합니다. 특정 예외를 사용하거나 (이 경우 IOException 및 XMLExcepetion이 있다고 생각하거나) 적어도 치명적인 예외는 정상적으로 throw 될 수 있습니다.

분명히 XML 파일을 수정하지 않으면 대단히 큰 파일을로드하는 동안 slownes/hangs가 발생할 수도 있습니다. 독자의 행동과 XML의 복잡성 (악의적 인 사용자에 의해 주어질 경우)에 따라 StackOverflow와 같은 일부 예외가 프로세스를 중지시킬 수 있습니다.

+0

안녕하세요 @Alexei 미안 해요. 늦은 응답에 대해 방금 나왔습니다. 나는 실제로 ** XML 파일을 제어하지 못합니다. 스레드 안전 부분에 대해 좀 더 설명해 주시겠습니까? 아이디어는 XML 파일을 한 번만로드하고 여러 번 사용하기 위해 메모리에 저장하는 것입니다. 응용 프로그램은 다음과 같이 실행되도록 예약 된 콘솔 응용 프로그램입니다. 특정 시간에 데이터베이스를 채우면 노드를 반복하고 데이터베이스에 추가하는 foreach 루프가 하나만있어 스레드 안전성에 문제가 있습니까? – Marko

+0

콘솔 응용 프로그램에 스레드 생성이나 기타 비동기 처리 (예 : QueueUserWorkItem)가 필요하지 않은 경우 코드의 스레드 안전성에 대해 걱정할 필요가 없습니다. 메서드가 여러 스레드에서 호출되는 경우 비 변경 가능 구조에 액세스하는 동안 스레드 간의 동기화에 대해 걱정할 필요가 있습니다 (예 : XDocument 메서드가 동시에 여러 스레드로부터 안전하게 액세스 할 수 있다는 보장은 없지만 사전은 이러한 액세스를 허용합니다. 수정이 없음). 정보를 찾으려면 "스레드 안전 코드 작성"을 검색하십시오. –

+0

"XML을 제어하지 못합니다."- 악의적 인 XML을 기대하거나 무효라고 생각하면 더 많은 의문이 생깁니다. 나중에 처리하기 쉽고 친숙한 환경에서 실행중인 비공개 도구에 대한 코드가 적합합니다. –