2010-08-27 10 views
9

Tengo una API que devuelve XElement, y quiero que el documento detrás de esos XElement sea inmutable (solo lectura). Lo necesito para:¿Hay alguna manera de crear un XDocument inmutable (de solo lectura)?

  • No dar desarrolladores la capacidad de cambiar accidentalmente :)
  • Mejorar el rendimiento - la creación de una copia de un XDocument podría ser una operación rendimiento "pesado" en algunos casos.

No parece posible heredar & reemplazar el comportamiento necesario en XDocument/XElement/XContainer, porque todos los métodos virtuales no están marcados como internal:

internal virtual void XContainer.AddAttribute(XAttribute a) 
{ 
} 

Así que mi pregunta es - es Hay alguna manera de hacerlo posible, o es mejor tener una API diferente que devuelva algo como XPathNavigator, o es mejor tener clases propias como IReadOnlyXElement, etc.?

Respuesta

4

Puede crear una envoltura XElement que sea similar a ReadOnlyCollection<T>.

public sealed class ReadOnlyXElement 
{ 
    private readonly XElement _element; 


    public string Value 
    { 
     get { return _element.Value; } 
    } 


    public ReadOnlyXElement(XElement element) 
    { 
     _element = element; 
    } 


    public IEnumerable<ReadOnlyXElement> Elements() 
    { 
     foreach (var child in _element.Elements()) 
     { 
      yield return new ReadOnlyXElement(child); 
     } 
    } 

    public IEnumerable<ReadOnlyXElement> Elements(XName xname) 
    { 
     foreach (var child in _element.Elements(xname)) 
     { 
      yield return new ReadOnlyXElement(child); 
     } 
    } 
} 
3

en mi humilde opinión, es probablemente mejor para hacer su propia clase contenedora para interactuar con XDocuments/XElements. A continuación, puede limitar la capacidad de un desarrollador para escribir sobre el archivo en el código.

digo límite porque con suficiente información (ubicación, esquema (si es necesario)) un desarrollador podría utilizar el stock XMLClasses para hacer lo que quisieran. El objetivo final sería hacer que el archivo sea de solo lectura en el disco y asegurarse de que ellos (desarrolladores, usuarios) no tengan permiso para cambiar el acceso de solo lectura en el archivo.

12

Dudo que el autor siga esperando respuestas, pero tal vez alguien más lo encuentre útil.

Usted puede tipo de hacer el XDocument inmutable utilizando su caso cambiante:

class Program 
    { 
     static void Main(string[] args) 
     { 
      var xdoc = XDocument.Parse("<foo id=\"bar\"></foo>"); 
      xdoc.Changing += (s, ev) => 
      { 
       throw new NotSupportedException("This XDocument is read-only"); 
      }; 

      try 
      { 
       xdoc.Root.Attribute("id").Value = "boo"; 
      } 
      catch (Exception e) 
      { 
       Console.WriteLine("EXCEPTION: " + e.Message); 
      } 

      Console.WriteLine("ID on exit: " + xdoc.Root.Attribute("id").Value); 

      Console.ReadKey(); 
     } 
    } 

// Console output: 
// EXCEPTION: This XDocument is read-only 
// ID on exit: bar 

No es la solución más bonito, pero proporciona un mecanismo básico para evitar cambios accidentales.

Cuestiones relacionadas