C# Type 序列化问题

原创 2011年01月21日 10:56:00

序列化时使用:type.AssemblyQualifiedName 将Type转换成字符串保存,

 

 

反序列化时使用如下方法:

 

Type.GetType(AN,T) actually translates to Assembly.Load(AN).GetType(T). This actually can be the cause of many confusions. Often programmers end up in a situation where they have explicitly loaded the assembly, but Type.GetType is not able to find the type from the assembly they just loaded.

 

Let us look into the sample below. Let us do a Type.GetType for Foo and provide the path to the location of Foo in the config file as mentioned below.

 

Copy the source below to TypeSample.cs and the config to TypeSample.exe.config

 

using System;

using System.Reflection;

class DomSample {

    public static void Main(){

        try {

            Type ty1 = Type.GetType("Foo, Foo, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1faea1974f697f94");

            if (ty1 != null) {

                Console.WriteLine("V1 Type = {0}", ty1.Assembly.FullName.ToString());

            }

            else {

                Console.WriteLine("Unable to find type ...");

            }

        }

        catch (Exception e) {

            Console.WriteLine(e.ToString());

        }

    }

}

 

<configuration>

   <runtime>

      <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">

         <probing privatePath="v1" />

      </assemblyBinding>

   </runtime>

</configuration>

 

 

Make sure that you create a path v1 under APPBASE and create a Foo.cs which is compiled and signed to Foo.dll. Copy the following source to Foo.cs and comple it to Foo.dll and sign it with the key (see my article on signinig)

 

using System;

using System.Reflection;

[assembly: System.Reflection.AssemblyVersion("1.0.0.0")]

public class Foo {

    public void Bar() {

        Console.WriteLine("Version = {0}", (Assembly.GetExecutingAssembly()).ToString());

    }

}

 

 

If you run TypeSample.exe you will get the following output

V1 Type = Foo, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1faea1974f697f94

 

If you run the sample under ntsd you will notice that Foo.dll is loaded from directory v1 in the default AppDomain

 

 

Opened log file 'ntsd.log'

0:000> !dumpdomain

--------------------------------------

System Domain: 7a390b60

LowFrequencyHeap: 7a390b84

HighFrequencyHeap: 7a390be0

StubHeap: 7a390c3c

Stage: OPEN

Name: None

--------------------------------------

Shared Domain: 7a391138

LowFrequencyHeap: 7a39115c

HighFrequencyHeap: 7a3911b8

StubHeap: 7a391214

Stage: OPEN

Name: None

Assembly: 001e8828

--------------------------------------

Domain 1: 001b0890

LowFrequencyHeap: 001b08b4

HighFrequencyHeap: 001b0910

StubHeap: 001b096c

Stage: OPEN

SecurityDescriptor: 001b1a98

Name: DomSample.exe

Assembly: 001e8828 [C:/Windows/assembly/GAC_32/mscorlib/2.0.0.0__b77a5c561934e089/mscorlib.dll]

ClassLoader: 001e88c0

SecurityDescriptor: 001e8738

  Module Name

790c2000 C:/Windows/assembly/GAC_32/mscorlib/2.0.0.0__b77a5c561934e089/mscorlib.dll

 

Assembly: 001f95e0 [c:/blog/May2007/DomSample.exe]

ClassLoader: 001f9678

SecurityDescriptor: 001f94e0

  Module Name

00712c24 c:/blog/May2007/DomSample.exe

 

Assembly: 00208128 [c:/blog/May2007/v1/Foo.dll]

ClassLoader: 00208398

SecurityDescriptor: 00208298

  Module Name

007130d8 c:/blog/May2007/v1/Foo.dll

 

 

Now let us modify the code above to use LoadFrom and then try the Type.GetType.

 

Copy the code below to TypeSampleLoadFrom.cs and compile it to TypeSampleLoadFrom.exe. Let us not provide a config file this time such Type.GetType cannot find the assembly Foo when it tries to load it.

 

using System;

using System.Reflection;

class DomSample {

    public static void Main() {

        try {

            Assembly.LoadFrom("c://Blog//May2007//v2//Foo.dll");

            Type ty1 = Type.GetType("Foo, Foo, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1faea1974f697f94");

            if(ty1 != null) {

                Console.WriteLine("V1 Type = {0}",ty1.Assembly.FullName.ToString());

            }

            else {

                Console.WriteLine("Unable to find type ...");

            }

        }

        catch(Exception e) {

            Console.WriteLine(e.ToString());

        }

    }

}

 

 

The above program yields the result "Unable to find type ...". If you watch the program under ntsd you will notice that Foo.dll is loaded from the LoadFrom, but the Type.GetType was not able to use the already loaded Foo.dll or find Foo.dll to load it to retreive the type information

 

 

0:001> !dumpdomain

--------------------------------------

System Domain: 7a390b60

LowFrequencyHeap: 7a390b84

HighFrequencyHeap: 7a390be0

StubHeap: 7a390c3c

Stage: OPEN

Name: None

--------------------------------------

Shared Domain: 7a391138

LowFrequencyHeap: 7a39115c

HighFrequencyHeap: 7a3911b8

StubHeap: 7a391214

Stage: OPEN

Name: None

Assembly: 002e86e8

--------------------------------------

Domain 1: 002b08c8

LowFrequencyHeap: 002b08ec

HighFrequencyHeap: 002b0948

StubHeap: 002b09a4

Stage: OPEN

Name: DomSample1.exe

Assembly: 002e86e8 [C:/Windows/assembly/GAC_32/mscorlib/2.0.0.0__b77a5c561934e089/mscorlib.dll]

ClassLoader: 002e8780

SecurityDescriptor: 002f4ef8

  Module Name

790c2000 C:/Windows/assembly/GAC_32/mscorlib/2.0.0.0__b77a5c561934e089/mscorlib.dll

 

Assembly: 002fa790 [c:/blog/May2007/DomSample1.exe]

ClassLoader: 002fa828

SecurityDescriptor: 002fa690

  Module Name

00102c24 c:/blog/May2007/DomSample1.exe

 

Assembly: 00302bc0 [c:/Blog/May2007/v2/Foo.dll]

ClassLoader: 003072b0

SecurityDescriptor: 00306b88

  Module Name

00103120 c:/Blog/May2007/v2/Foo.dll

 

 

Let us modify the above sample and add a config TypeSampleLoadFrom.exe.config as follows

 

<configuration>

   <runtime>

      <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">

         <probing privatePath="v1" />

      </assemblyBinding>

   </runtime>

</configuration>

 

You will get the output  V1 Type = Foo, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1faea1974f697f94.

 

If you run the program under the debugger you will find that there are two Foo.dll loaded in the default AppDomain one loaded from the LoadFrom context and the other load by Type.GetType in the other context. I had specifically placed the same Foo.dll in different locations to make this happen. The Foo.dll loaded by Type.GetType was loaded from v1 directory and the Foo.dll loaded from the LoadFrom context was loaded from v2 directory. If you had both point to the same location, you will however see only one copy of the dll.

 

0:000> !dumpdomain

--------------------------------------

System Domain: 7a390b60

LowFrequencyHeap: 7a390b84

HighFrequencyHeap: 7a390be0

StubHeap: 7a390c3c

Stage: OPEN

Name: None

--------------------------------------

Shared Domain: 7a391138

LowFrequencyHeap: 7a39115c

HighFrequencyHeap: 7a3911b8

StubHeap: 7a391214

Stage: OPEN

Name: None

Assembly: 003386f8

--------------------------------------

Domain 1: 003008a0

LowFrequencyHeap: 003008c4

HighFrequencyHeap: 00300920

StubHeap: 0030097c

Stage: OPEN

SecurityDescriptor: 00301aa8

Name: DomSample1.exe

Assembly: 003386f8 [C:/Windows/assembly/GAC_32/mscorlib/2.0.0.0__b77a5c561934e089/mscorlib.dll]

ClassLoader: 00338790

SecurityDescriptor: 00344ed0

  Module Name

790c2000 C:/Windows/assembly/GAC_32/mscorlib/2.0.0.0__b77a5c561934e089/mscorlib.dll

 

Assembly: 0034a7c8 [c:/blog/May2007/DomSample1.exe]

ClassLoader: 0034a860

SecurityDescriptor: 0034a6c8

  Module Name

002d2c24 c:/blog/May2007/DomSample1.exe

 

Assembly: 00365b00 [c:/Blog/May2007/v2/Foo.dll]

ClassLoader: 00365998

SecurityDescriptor: 00358038

  Module Name

002d3120 c:/Blog/May2007/v2/Foo.dll

 

Assembly: 00366bd0 [c:/blog/May2007/v1/Foo.dll]

ClassLoader: 00366a58

SecurityDescriptor: 00365c48

  Module Name

002d3548 c:/blog/May2007/v1/Foo.dll

 

参考文章:

http://blogs.msdn.com/b/thottams/archive/2007/05/11/load-contexts-and-type-gettype.aspx

 

http://stackoverflow.com/questions/629666/c-type-gettype-called-from-a-dll-on-exe-type-string


本文来自SunShine,转载请标明出处:http://do.jhost.cn/sunshine/ReadNews?action=read&id=244

相关文章推荐

C#中泛型集合List<T>反序列化问题及解决方法

在不同程序集中使用反序列化技术时需要考虑类型所在的程序集问题。特别地,针对反序列化泛型集合List<T>,还需要有更直接的处理方式。本文介绍了一个处理泛型集合List<T>的反序列化方法,在VS201...
  • hulihui
  • hulihui
  • 2015年10月08日 08:44
  • 5145

c#序列化 ajax

  • 2013年03月12日 15:58
  • 20KB
  • 下载

C# 中字体和颜色的XML序列化

C#中提供的XmlSerializer类可以将Object序列化到xml文档,也可以从xml文档中反序列化对象 XmlSerializer中的Serialize和Deserialize方法可以用于Ob...
  • openzpc
  • openzpc
  • 2015年08月26日 11:42
  • 1025

C#中Font和Color的Xml序列化

  • 2015年08月26日 16:56
  • 60KB
  • 下载

C# XML和类之间的转化,序列化

  • 2013年11月14日 14:13
  • 38KB
  • 下载

C# 调用Webservice并传递序列化对象

C# 调用Webservice并传递序列化对象 分类: c#_WebService2013-03-08 15:40 7287人阅读 评论(1) 收藏 举报 C#动态调用WebSer...

C#序列化

  • 2008年07月02日 15:35
  • 81KB
  • 下载

C# 单文件存放多个序列化对象

  • 2010年01月20日 19:27
  • 15KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C# Type 序列化问题
举报原因:
原因补充:

(最多只允许输入30个字)