Reflection: System.Reflection

< BACK  NEXT >
[oR]

Every assembly includes metadata. Always having metadata available is handy; it allows creating useful features such as Visual Studio's IntelliSense, which automatically displays the methods available for a class and other useful information. But metadata is just information sitting in a file. It's useless without software that knows how to read and interpret that metadata. To support this software, it's useful to have a standard interface to an assembly's metadata, one that can be used by all kinds of applications.

An assembly's metadata is useless without some way to access it

Why Have Two Different XML Serializers?

At first glance, the XmlSerializer class in System.Xml.Serialization appears to do the same thing as the SoapFormatter class in the System.Runtime.Serialization.For-matters.Soap namespace. Both can serialize and deserialize the state of language objects to and from an XML representation. Why have both of them?

The answer lies in what each is intended to do. XmlSerializer attempts to produce standard XML, that is, XML that can be described using the XML Schema definition language, and it offers developers precise control over how that serialization happens. Because of this strong focus on standard XML, there are some aspects of the CLR type system that it cannot correctly serialize. For example, XML has no notion of private data, so when, say, a C# object with private members is serialized by the XmlSerializer, only the object's public members are included in the result. Accurately recreating the object given only the output of the XmlSerializer wouldn't be possible in this case some information has been lost. If your goal is to produce completely XSD-compliant XML, however, this is the XML serialization option that you should choose. For example, ASP.NET's support for Web services uses the XmlSerializer to generate the XML it sends because those Web services are meant to be accessible from all kinds of systems.

The SoapFormatter, by contrast, is intended for use with .NET Remoting. Accordingly, this serialization engine wraps its output in a SOAP envelope, making it less useful for generalized XML work. More important, however, .NET Remoting typically assumes that the .NET Framework is on both sides of the communication, and so the interaction does not need to take into account anything but .NET. As a result, the SoapFormatter's primary goal is to reproduce the CLR types faithfully in XML. A CLR object serialized with the SoapFormatter can be exactly reconstructed by the receiving system's SoapFormatter private members and everything else are transmitted correctly but a non-Microsoft implementation would likely have trouble understanding some of the information it receives.

Mapping between different type systems is almost always challenging. Converting CLR types into XML types has its problems, as does the reverse translation, and different applications need to do it in different ways. Accordingly, the .NET Framework class library provides two choices for doing this translation.

For managed code, that interface is provided by the types contained in the System.Reflection namespace. Before taking a look at these types, recall what metadata consists of: information about the types in an assembly, such as what methods they implement, and information about the assembly itself, stored in the assembly's manifest. As mentioned in Chapter 3, the Ildasm tool can be used to examine an assembly's metadata. Figure 5-4 shows how Ildasm displays the metadata stored with the simple example application from Chapter 4. The manifest appears first, followed by entries for each of the three outermost types in the program: the classes Compute and DisplayValues and the interface IMath. Each of these has associated information, the most interesting of which is the methods each type implements. Note that along with the familiar methods shown in Chapter 4's code, each class also has a constructor, labeled .ctor in the Ildasm display.

Figure 5-4. The metadata stored with Chapter 4's simple example application can be displayed using Ildasm.
graphics/05fig04.gif

The types in System.Reflection allow managed code to access metadata

To allow programmatic access to this information, the System.Reflection namespace includes a class for each type of information in an assembly's metadata. An application can create instances of these classes as needed and then populate them with the appropriate information from a particular assembly. As Figure 5-5 shows, instances of these classes are organized into a hierarchy. Once the appropriate instances have been created Figure 5-5 shows a fairly complete picture for Chapter 4's sample application the assembly's metadata can be accessed.[3]

[3] It's worth pointing out that full access to metadata requires appropriate code access security permissions.

Figure 5-5. The classes in System.Reflection can be used to create a hierarchical in-memory structure that contains an assembly's metadata.
graphics/05fig05.gif

Each kind of metadata is represented by a specific class

Although it's not shown in the diagram, it's also possible to access any attributes this metadata contains.

For example, to list all methods contained in this assembly's Compute class, an application could create an instance of the Assembly class and then call this class's LoadFrom method with the name of the file containing the assembly. The Assembly class also provides a GetModule method that can be used to return an instance of the Module class that describes the module containing the Compute class. Once this Module instance exists, the application can call GetType with the name of the desired type in this module, which in this case is Compute. The result is an object of the class Type[4] that contains information about the Compute class. The Type class provides a large set of methods and properties for learning about its contents. For example, a call to Type.GetMethods can return a description of all methods that type implements, each contained in an instance of the class MethodInfo. In this case, three MethodInfo objects would be returned, each containing information about one of Compute's three methods. By examining the properties of each MethodInfo, the application can learn whatever it needs to know about these methods. Among the information available is the method's name, the types of its parameters, its return type, whether the method is final (sealed), and much more.

[4] This is the same Type that is returned by calls to GetType, one of the methods in the Object type that is the root of all others in the CLR type system. Because of this, Type is defined in the System namespace rather than in System.Reflection.

The Reflection namespace also contains the subordinate namespace Reflection.Emit. To understand what the types in this namespace do, it's first important to understand the two types of assemblies that can be used by the .NET Framework. As described in Chapter 3, the most common variety, static assemblies, are stored on and loaded from disk. All assemblies described so far have in fact been static assemblies. It's also possible to create dynamic assemblies, assemblies that are created directly in memory. With this approach, a running application creates MSIL code and metadata, building an assembly on the fly, and then executes it. The types in the Reflection.Emit namespace are used to do this.

The types in Reflection.Emit allow creating assemblies dynamically

Creating dynamic assemblies is not for the faint of heart. Reflection.Emit contains types that do very low-level things, including generating MSIL code one instruction at a time. Yet while most developers probably won't work directly with these types, it's useful to know that they exist. Class libraries are meant to make developers' lives easier, and you can't use code in a library if you don't know the code is there.

Types in Reflection.Emit allow applications to generate explicitly and then execute MSIL code

< BACK  NEXT >


Understanding. NET. A Tutorial and Analysis
Understanding .NET: A Tutorial and Analysis (Independent Technology Guides)
ISBN: 0201741628
EAN: 2147483647
Year: 2002
Pages: 60

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net