2009-03-24 7 views
8

.NETでXmlSerializerインスタンスを構築するときに、指定された型をシリアル化および逆シリアル化するためのアセンブリが動的に生成されます。これは時間のかかるプロセスです。 Microsoftのsgen.exeツールを使用して、XmlSerializerインスタンスをプリコンパイルして、後でそれらを動的に生成せずに使用することができます。残念ながら、これはXmlAttributeOverridesを使用するXmlSerializerインスタンスでは不可能です。XmlSerializerをXmlAttributeOverridesでプリコンパイルする

実行時に生成されないように、これらのXmlSerializerインスタンスをプリコンパイルする方法はありますか。

+0

これ以上のことはありませんか? – Rory

答えて

6

Andreas、これはsgenツール自体の問題ではありません。これはXmlSerializerの実装によるものです。

Type引数が1つのみのコンストラクタを使用してXmlSerializerのインスタンスを作成すると、キャッシュに入り、事前生成されたアセンブリが検索されます。 ただし、XmlAttributeOverridesでコンストラクタを使用すると、XmlSerializerはキャッシュをチェックせず、すぐにtempアセンブリを生成します。

これは、おそらく、XmlAttributeOverrides引数を使用してシリアル化ロジックが大幅に変更されたためです。これは、sgenのようなツールではコンパイル時に "予見できない"ことがあります。

事前にコンパイルしておく必要がある場合は、XmlAttributeOverridesを回避する必要があります。これが不可能な場合は、事前に必要なXmlSerializerインスタンスをバックグラウンドスレッドで作成してみてください。

ちょうどあなたの興味のために、ここではデフォルトコンストラクタ(チェックがキャッシュし、事前に生成されたアセンブリを見つけようとします)のコードです:XmlAttributeOverridesで使用するコンストラクタは(常にシリアライズを生成している

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); 
     } 
    } 
} 

そして、ここでは、アセンブリ):

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

ああ、私はこの同じ問題に遭遇しました。残念ながら、私はcsc.exe(プロテクトモードのInternet Explorerから実行しています)を起動できないため、シリアル化アセンブリの動的作成を使用できません。助言がありますか?私は、XmlSerializerで作成したtemp .csファイルをキャプチャして、ビルドに含め、XmlSerializerの代わりに直接使用すると考えています。音が乱雑ですが、他のアイデアはありますか?ここで私のqn:http://stackoverflow.com/questions/7333689/generating-an-xml-serialization-assembly-for-a-custom-xmlserializer – Rory

関連する問題