2009-03-24 24 views
8

Khi xây dựng các cá thể XmlSerializer trong .NET, các assembly để tuần tự hóa và deserializing kiểu được chỉ định được tạo động. Đây là một quá trình tốn thời gian. Công cụ sgen.exe của Microsoft có thể được sử dụng để biên dịch trước các cá thể XmlSerializer để sử dụng chúng sau này mà không sinh ra chúng một cách động. Thật không may điều này là không thể với XmlSerializer trường hợp sử dụng XmlAttributeOverrides.XmlSerializers biên dịch trước với XmlAttributeOverrides

Có cách nào để biên dịch trước các phiên bản XmlSerializer này để tránh tạo trong thời gian chạy không?

+0

Bạn có tiếp tục ở đâu với điều này không? – Rory

Trả lời

6

Andreas, đây không phải là vấn đề của chính công cụ sgen, điều này là do triển khai XmlSerializer.

Khi bạn tạo một thể hiện của XmlSerializer, sử dụng hàm tạo với chỉ một đối số Kiểu, nó đi và kiểm tra bộ nhớ cache và tìm kiếm các hội đồng được tạo trước. Nhưng khi bạn sử dụng hàm tạo với XmlAttributeOverrides, XmlSerializer sẽ không kiểm tra bất kỳ bộ nhớ đệm nào và sẽ tạo ra cụm tạm thời ngay lập tức.

Rất có thể, đó là do những thay đổi hoàn toàn trong logic tuần tự hóa mà bạn có thể đạt được bằng cách sử dụng đối số XmlAttributeOverrides, không thể "được dự đoán" trong thời gian biên dịch bằng các công cụ như sgen.

Nếu bạn cần phải có mọi thứ được biên dịch trước, bạn [thở dài] phải tránh XmlAttributeOverrides. Nếu điều này là không thể, hãy thử tạo các cá thể XmlSerializer được yêu cầu trước thời hạn, có thể trong một chuỗi nền.

Chỉ cần sự quan tâm của bạn, đây là mã cho các nhà xây dựng mặc định (kiểm tra bộ nhớ cache và cố gắng tìm một hội đồng tiền tạo ra):

public XmlSerializer(Type type, string defaultNamespace) 
{ 
    this.events = new XmlDeserializationEvents(); 
    if (type == null) 
    { 
     throw new ArgumentNullException("type"); 
    } 
    this.mapping = GetKnownMapping(type, defaultNamespace); 
    if (this.mapping != null) 
    { 
     this.primitiveType = type; 
    } 
    else 
    { 
     this.tempAssembly = cache[defaultNamespace, type]; 
     if (this.tempAssembly == null) 
     { 
      lock (cache) 
      { 
       this.tempAssembly = cache[defaultNamespace, type]; 
       if (this.tempAssembly == null) 
       { 
        XmlSerializerImplementation implementation; 
        Assembly assembly = TempAssembly.LoadGeneratedAssembly(type, defaultNamespace, out implementation); 
        if (assembly == null) 
        { 
         this.mapping = new XmlReflectionImporter(defaultNamespace).ImportTypeMapping(type, null, defaultNamespace); 
         this.tempAssembly = GenerateTempAssembly(this.mapping, type, defaultNamespace); 
        } 
        else 
        { 
         this.mapping = XmlReflectionImporter.GetTopLevelMapping(type, defaultNamespace); 
         this.tempAssembly = new TempAssembly(new XmlMapping[] { this.mapping }, assembly, implementation); 
        } 
       } 
       cache.Add(defaultNamespace, type, this.tempAssembly); 
      } 
     } 
     if (this.mapping == null) 
     { 
      this.mapping = XmlReflectionImporter.GetTopLevelMapping(type, defaultNamespace); 
     } 
    } 
} 

Và đây là các nhà xây dựng sử dụng với XmlAttributeOverrides (luôn luôn tạo ra serialization assembly):

public XmlSerializer(Type type, XmlAttributeOverrides overrides, Type[] extraTypes, XmlRootAttribute root, string defaultNamespace, string location, Evidence evidence) 
{ 
    this.events = new XmlDeserializationEvents(); 
    if (type == null) 
    { 
     throw new ArgumentNullException("type"); 
    } 
    XmlReflectionImporter importer = new XmlReflectionImporter(overrides, defaultNamespace); 
    for (int i = 0; i < extraTypes.Length; i++) 
    { 
     importer.IncludeType(extraTypes[i]); 
    } 
    this.mapping = importer.ImportTypeMapping(type, root, defaultNamespace); 
    if (location != null) 
    { 
     this.DemandForUserLocation(); 
    } 
    this.tempAssembly = GenerateTempAssembly(this.mapping, type, defaultNamespace, location, evidence); 
} 
+0

Ah, tôi đã gặp phải vấn đề tương tự này. Thật không may tôi _can't_ sử dụng năng động sáng tạo của hội đồng serialization vì tôi không thể khởi động csc.exe (đang chạy từ chế độ bảo vệ Internet Explorer). Bất kỳ đề xuất? Tôi nghĩ rằng tôi có thể nắm bắt các tập tin .pp tạm thời được tạo ra bởi XmlSerializer, bao gồm trong xây dựng của tôi và sử dụng mà thay vì XmlSerializer trực tiếp. Âm thanh lộn xộn nhưng bất kỳ ý tưởng nào khác? Qn của tôi ở đây: http://stackoverflow.com/questions/7333689/generating-an-xml-serialization-assembly-for-a-custom-xmlserializer – Rory

Các vấn đề liên quan