Presentation is loading. Please wait.

Presentation is loading. Please wait.

Q Reflection Nauzad Kapadia MGB 2003

Similar presentations


Presentation on theme: "Q Reflection Nauzad Kapadia MGB 2003"— Presentation transcript:

1 Q Reflection Nauzad Kapadia MGB 2003
© 2003 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.

2 Contents Section 1: Overview Section 2: Exploring Metadata
Section 3: Detail Information Section 4: Building Types at Runtime Section 5: Putting it together Summary

3 Section 1: Overview Looking back: Automation and COM Type Info
What's wrong with that? .NET Reflection Core Concepts

4 Looking Back: Automation
MGB 2003 Looking Back: Automation TypeLibraries contain type information Exploration through ITypeLib/ITypeInfo Attributes describe behavior of elements e.g. Directionality of parameters e.g. Method role (instance method, property) Dynamic Invocation using IDispatch Type system supports most popular simple types Dynamic types using VARIANT Arrays passed using SAFEARRAY Strings expressed as BSTR Reflection is all about Metadata and the structural composition of applications. Of course, this concept is not new. Therefore we will first look back at how type description and type exploration could be performed in the COM world. Type libraries contain type information In COM, most type information is contained in type libraries. A type library is a binary file, which is provided alongside with or embedded in the server component. Type libraries can be explored through the ITypeLib and ITypeInfo interfaces and are generated by the MIDL compiler. Attributes describe behavior of elements The type information contained in these libraries is attributed. Each interface, method or argument can be augmented with attributes, which describe their behavior. These are for instance the [in] or [out] attributes for method arguments, which define the directionality of marshaling. Other attributes allow to distinguish between simple instance methods and methods that are used to set or gets property values. The interface identifier is also associated with the interface declaration using an attribute. Dynamic Invocation using IDispatch The COM "automation" model allows late binding through the IDispatch interface. The IDispatch interface allows the dynamic expiration of type descriptions, which the server may either retrieve and expose from a type library or will dynamically create at runtime. The type information that is exposed through the IDispatch interface is structurally identical to the information model of ITypeInfo. Type system supports most popular simple types The type system that can be used with COM and through the ITypeInfo, ITypeLib and IDispatch interfaces supports the most popular simple data types, but is very limited in supporting complex types. Because COM is a binary standard, types that require a certain in-memory organization (like strings) are COM-native and need special handling or care by the server and client implementers. Dynamic types using VARIANT Dynamic types are available through the VARIANT data type. Variants are COM's universal containers, which can transport values of all native COM data types. Arrays passed using SAFEARRAY Arrays of values are past using the SAFEARRAY type. The SAFEARRAY is special structure, which allows passing multidimensional blocks of homogeneous types between COM components. Strings expressed as BSTR COM strings are expressed as BSTR types, which is a zero terminated string with two lead bytes that indicate the length of the string. © 2003 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.

5 What's wrong with that? Automation client model favors VisualBasic
MGB 2003 What's wrong with that? Automation client model favors VisualBasic Automation server model favors C/C++ ITypeInfo and IDispatch are way too complicated Information model is limited No sufficient support for complex types SAFEARRAYs are a pain from C/C++ BSTRs are difficult to manage from C/C++ Type information separate from code Automation client model favors VisualBasic The main problem with automation is that the client model clearly favors Visual Basic another rapid application development languages, where the underlying runtime can hide much of the complexity. Automation server model favors C/C++ The server side, however, is better supported by low-level languages such as C and C++, because only those allow a level control that lets you leverage all features of the COM automation infrastructure which can then be exposed to and consumed by automation clients. This is in line with original vision of automation, where Visual Basic was thought to be used as a language that could control but not necessarily implement large COM servers. This has of course changed or while ago, but the bias in the COM infrastructure is still visible. ITypeInfo and IDispatch are way too complicated Exploration of the ITypeInfo and IDispatch information is a very complicated task. There are a few dozen of structures to deal with the navigation through the type information is neither is straightforward nor easy. So although quite a few aspects of attributed programming as it is now promoted in the .NET world, is possible in COM with type libraries and custom attributes that can be added to those libraries. But because evaluating this type information is a complicated and was never really seen a serious option for most developers. A good example for this extensibility are the custom type library attributes that are available for COM+ and the Microsoft Transaction Server, which allow you to flag components as transactional in the IDL file, and when imported into COM+ these attributes are being read and the components are configured correctly. Information model is limited, no support for complex types Another problem is that the information model is too limited. While it has been proven millions of times, that the COM information and type model is sufficient for most scenarios, the lack of ability to marshal complex types through the dynamic binding interfaces has often lets the implementation of wrapper interfaces around structures, which should technically have been marshaled by value and made available natively to the client application. Doing so without implementing custom marshaling through IMarshal (which is not a widespread skill or dare) will result in objects being exposed by reference and increased traffic between client and server. SAFEARRAYs are a pain from C/C++ The SAFEARRAY type, which is COM's native array, needs a lot of very special attention in C and C++ programs through a special API, which can only be described as being a pain in terms of usability. BSTRs are difficult to manage from C/C++ The BSTR string type is also problematic and a common source of bugs in COM applications, because it looks suspiciously like any other zero-terminated string but requires special allocation and de-allocation functions. Type information separate from code Another issue is that the type information is separate from the code. Just as you have "DLL hell" with multiple versions of the same components on the same machine, there exists a very related problem with multiple type libraries for these different versions. © 2003 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.

6 .NET Reflection Core Concepts
MGB 2003 .NET Reflection Core Concepts Metadata Single location for type information and code Code is literally contained within type information Every .NET object can be queried for its type Types' metadata can be explored with Reflection Dynamic Type System Highly dynamic and language independent Types may be extended and built at run-time Allows on-the-fly creation of assemblies .NET Compilers use .NET to emit .NET code .NET reflection and its core concepts build on the experience of the COM type library model. Applications are able to evaluate the type information at runtime and invoke services in a late bound fashion. The two core elements that enable this are "Metadata" and .NET's dynamic common type system. Metadata Metadata provides a single location for the type information and code. In .NET assemblies of the entire structural information about application is bundled together with a description of its runtime behavior, expressed in the Microsoft intermediate language. The structural information describes the overall shape of assemblies and modules into detail each data type and class. Class methods and all other active entities are stored with their call signature and return value types and their MSIL code. MSIL is therefore really part of the description of any method, because the actual code that is executed at runtime is a compiled representation of the MSIL in native machine code. While the COM type library information is restricted to those types for which inclusion in the library was explicitly requested, Metadata is available and accessible for each and every type that is being used in .NET managed code. Every .NET types, from simple scalar types such as a plain integer to complex classes can be queried for its type. At runtime, data types are represented by special .NET runtime class, System.Type. This class allows close inspection of every aspect of a runtime data type. The framework's ability to make type information available at runtime through this class is what is called "reflection". Dynamic Type System The universal exploration of type information is enabled by the dynamic common type system (CTS). All languages that target the .NET framework share the CTS. The language compilers automatically create the type information stored in the Metadata, which can later be read by applications written in any other language. Because the underlying type system is now independent of the implementation language used, the restricted type model that we know from COM no longer applies and the exchangeable type information is equivalent to the type information used to build applications. Under the hood, the type information exposed through reflection is sometimes even richer than what can be expressed using the intrinsic language elements of languages like C#. The "Emit" part of reflection, which is covered in the second part of this module allows types the extended (by inheritance) or be entirely build at runtime. This allows for the on the fly creation of new assemblies and modules and in fact .NET compilers use .NET to emit .NET code. © 2003 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.

7 Exploring Metadata Who are you? What are you?
Anything special about you? Now tell me what you have! Types and Instances

8 MetaData: Type Info at Runtime
MGB 2003 MetaData: Type Info at Runtime [serializable] public class Person : { public event OnSaveChange onsv; public Date DOB; public string FirstName; public string LastName; public string Name { get { return FirstName + " " + LastName; } } public void Person(string First,string Last) { FirstName=First;LastName=Last; } public bool Save() { System.Type t = this.GetType(); foreach( FieldInfo f in t.GetFields() ) { ... } } System.Type Attributes Events Fields Properties The illustration in the associated slide unravels much of the mystery of Reflection. Essentially, once you are able to grasp what the slide is demonstrating, you have already entirely understood what Reflection is all about. In the illustration you see that the code in the method “Save” invokes the method “GetType()” on the object’s “this” self-reference. This method is always available on any .NET class, since it is a member of the fundamental System.Object class that is the base for any managed code class, regardless of whether you explicitly declared that inheritance relationship. All .NET compilers will establish that relationship automatically “under the hood”. The method “GetType()” returns an instance of the System.Type class, which encapsulates access to all Metadata of the object you “asked”. The System.Type instance will allow you to traverse into all details of the type or class (excluding, specifically, the IL code) and also explore the environment like the implementing module and container assembly. The following discussion will center on System.Type and look at the capabilities of this single class in very much detail. Constructors Parameters Methods © 2003 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.

9 Reflection MetaData Samples
MGB 2003 Reflection MetaData Samples // Test sample class public class Test { private int n; public Test(int a) { n=a;} ... } //Retrieve the Type object public static int Main(string[] args) { Type type1 = typeof(Test); Test t1 = new Test(0); Type type2 = t1.GetType(); Console.WriteLine(“type of t1 is (0)”, type2); return 0 This example illustrates the basic concepts of the Reflection: the typeof operator and the GetType() method. A Type object can be retrived using the GetType() method or the typeof operation, depending on whether you are using a class name or an object reference. The output from this piece of code will be: “Type of t1 is Reflect.Test” © 2003 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.

10 Who are you? Accessing meta-data: System.Object.GetType()
MGB 2003 Who are you? Accessing meta-data: System.Object.GetType() All .NET classes (implicitly) inherit System.Object Available on every .NET class; simple types too Explicit language support for type meta-data C#, JScript.NET: typeof(…) VB.NET: If TypeOf … Is … Then … Determining Type Identity Types have unique identity across any assembly Types can be compared for identity if ( a.GetType() == b.GetType() ) { … }; Accessing metadata: System.Object.GetType() To sum up what you could see on the diagram: Because everything is essentially a class in .NET and all classes are derived from System.Object, which exposes the Reflection “gateway” GetType() as one of the most fundamental mechanisms in .NET, you can reflect every single type in .NET, including the simple, scalar types such as plain integers. Explicit language support for type metadata Although this mechanism is intrinsic to every object, the .NET languages have additional keywords and helpers to use and access Metadata though Reflection. The issue with GetType() is, of course, that it only works on active instances and not on class expressions as such. In C# and JScript.NET you can therefore use the intrinsic typeof(classname) expression to obtain the Metadata for the class without having to create an instance. The alternative for Managed C++ and Visual Basic.NET is of course to use the “System.Type.GetType(‘classname’)” method, but at the price that you need to express the class with it’s fully qualified namespace while you can just use a scoped expression in C# or Jscript.NET (that is, without the namespace qualifiers). In Visual Basic.NET you can use the “TypeOf” operator as part of an “If … Then … Else” expression to test whether an arbitrary variable expression is of a certain class type. Determining Type Identity Each type that you declare has a unique identity across any assembly. Because of .NET’s ability to assign “strong names” to assemblies to make their definition space globally unique, each type indirectly also gains this uniqueness quality. Furthermore, the mandatory namespace use in .NET further eliminates the collision potential. If you want to determine whether two expressions are of identical type, you can therefore directly compare their type objects. © 2003 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.

11 System.Type Access to meta-data for any .NET type
MGB 2003 System.Type Access to meta-data for any .NET type Returned by System.Object.GetType() Allows drilling down into all facets of a type Category: Simple, Enum, Struct or Class Methods and Constructors, Parameters and Return Fields and Properties, Arguments and Attributes Events, Delegates and Namespaces The core of all things in Reflection is really System.Type Access to metadata for any .NET type Every instance of System.Type is a dynamically created wrapper around the Metadata of certain class. When you invoke “GetType()” on an object, the runtime will gather the requested Metadata, stuff it into a fresh System.Type instance and hand it to you. Returned by System.Object.GetType() Instances of the System.Type class are most prominently returned by the System.Object.GetType() method as this has been shown previously, but as you descend into the depths of the .NET framework you will find that Type objects are used quite often throughout the lower-levels of the Framework hierarchy. Allows drilling down into all facets of a type The System.Type class will allow you to explore all facets of a type like the type “category”, a class’ or structure’s methods, constructors and their parameters and return values. Furthermore, of course, all other aspects of such types like properties, fields, events and delegates and, of course, the namespace the class is located in can be explored. © 2003 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.

12 What are you? Value, Interface or Class? Public, Private or Sealed ?
MGB 2003 What are you? Value, Interface or Class? IsValueType, IsInterface, IsClass Public, Private or Sealed ? IsNotPublic, IsSealed Abstract or Implementation? IsAbstract Covers all possible properties of a managed type Very intuitive API, no "Parameter Hell" When we zoom in on the System.Type class you will find that we can ask quite a few very precise and very simple questions through its methods as this is shown on the slide. Covers all possible properties of a managed type These very plain calls indeed expose all core information of a managed type. Very intuitive API, no "Parameter Hell" The bottom line here is simplicity. You do not need to haggle around with flags buried in bit-fields, but can just ask a very readable and clear question and get a “yes” or “no” response. Especially to C/C++ developers this may look a bit too verbose at first, but if you really go back into your own code you will find that while you typically retrieve such information encoded into a single bit-field (like a 32bit unsigned integer), for instance when using the Win32 API, you mostly end up testing the values individually by isolating them from the set. © 2003 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.

13 Anything special about you?
MGB 2003 Anything special about you? Special Memory Layout? IsAutoLayout IsExplicitLayout IsLayoutSequential COM Objects? IsCOMObject More… IsUnicodeClass IsSpecialName, etc. Here you have some of the more advanced “Is questions” for the System.Type class. Special Memory Layout? For P/Invoke and COM/Interop purposes, structures may be declared with special memory layout rules that define exactly how the data of a structured is rendered into a memory block when it is passed into and from unmanaged code. The three properties “IsAutoLayout”, “IsExplicitLayout” and “IsLayoutSequential” will tell you whether the in-memory layout is automatic (managed) or if any special rules apply. Typically, there is little reason for you to query these properties, because you will very likely not be able to make too much use of that information. The existence of these methods does, however, demonstrate how essential Remoting is for the Framework itself. When an object is passed to managed code, the P/Invoke and COM/Interop layers will indeed use the information obtained through Reflection to properly format the outgoing and incoming binary data blocks. COM Objects and Unmanaged Types? You can also tell whether an object is really a proxy to a COM object. There are a set of special rules such as restrictions in implementation inheritance when integrating COM classes into .NET applications or you may want to explicitly release and discard the COM object from its Runtime Callable Wrapper (RCW) and this is a way to tell whether this applies to a certain object. © 2003 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.

14 Now tell me what you have!
MGB 2003 Now tell me what you have! Finding and Exploring Members MemberInfo: GetMembers(), FindMembers() Exploring Fields and Properties FieldInfo: GetFields(), PropertyInfo: GetProperties() Exploring Constructors, Methods and Events GetConstructors(), GetMethods(), GetEvents() Exploring attributes, determining implemented interfaces, enumerating nested types, … Summary: Everything you may ever want to know Complex types have much more to offer and tell than their name and fundamental properties. The “Get*” methods of the System.Type provide access to the fields, properties and methods of a managed type. Finding and Exploring Members For generic access to all members, independent of their exact role, you can either use the “GetMembers()” method to retrieve a complete array of MemberInfo structures (to be explained in detail a bit later) or seek for a certain member by name using the “FindMembers” method. If you want to get only the fields or methods, you can use one of the role-dependent access methods: Exploring Fields, Properties, Constructors, Methods and Events To get an enumerable array of members arranged by the role they play in the context of a class you can call the respective function. If you want to have all fields, you call “GetFields()”, for properties “GetProperties()” , etc. Exploring attributes, determining implemented interfaces, enumerating nested types, … Likewise, there are methods that give you access to the attributes that are declared on a type and you can also retrieve a list of implemented interfaces and types that are declared within the scope of the current type. Summary: Everything you may ever want to know In short, every structural element that you can express in a language like C# is available through reflection. © 2003 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.

15 Type and Instances Type Safety First! Type checking at runtime
MGB 2003 Type and Instances Type Safety First! Type checking at runtime C#: if ( o is Customer ) { … } VB: If TypeOf o Is Customer Then … End If Dynamic Invocation through Reflection Support for late binding MethodInfo.Invoke() FieldInfo.SetValue() PropertyInfo.SetValue() Type Safety First! Type checking at runtime In summary, the information available through Reflection allows for more type-safe programming resulting in more solid code. You are now able to do runtime type-checks throughout the .NET platform by actively checking types before you execute an action instead of catching type-cast exceptions (or worse) after you have attempted to execute something on a non-matching type. The C# and Visual Basic.NET languages, like other languages available for the .NET platform, exposes this capability through an extra language keyword. If C# you can test an instance of a class using a “object is class” expression and in VB.NET you can use the more verbose “If TypeOf object Is class Then …” expression. Dynamic Invocation through Reflection Reflection will not only let you walk through types to obtain information about them, but will also let you make calls to class instances, if you use Reflection to implement late bound behavior. Methods can be invoked through Invoke() on the MethodInfo objects returned by GetMethods() and fields can be set with the SetValue() method on the FieldInfo objects returned by GetFields() or on the PropertyInfo returned by GetProperties(). © 2003 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.

16 Detail Information MemberInfo FieldInfo, PropertyInfo
MGB 2003 Detail Information MemberInfo FieldInfo, PropertyInfo ConstructorInfo, MethodInfo The System.Type class returns a lot of information by using helper classes such as the MemberInfo class. In this section we are taking a closer look at these classes and also how to obtain information on the larger context of a reflected class. You will also learn about Reflection’s unmanaged sibling, the Metadata API, which makes .NET Metadata natively available to unmanaged code. © 2003 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.

17 MemberInfo Base class for all "member" element descriptions
MGB 2003 MemberInfo Base class for all "member" element descriptions Fields, Properties, Methods, etc. Provides member kind, name and declaring class MemberInfo MethodBase ParameterInfo FieldInfo EventInfo PropertyInfo Base class for all "member" element descriptions The MemberInfo class is the base class of all Reflection information classes for subordinate elements of System.Type. If you enumerate all members of a type using the System.Type.GetMembers() method, an array of MemberInfo objects will be returned that will provide you with basic information about every subordinate element and you can indeed use Reflection itself to test whether a given MemberInfo is of type MethodInfo and do a safe type-cast to explore the specific capabilities. Provides member kind, name and declaring class The MemberInfo base class provides information about the element’s name, its “kind” (that is whether it is indeed a method, field or on of the other kinds) and which its declaring class is. MethodInfo ConstructorInfo © 2003 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.

18 Reflection Dynamic Creation Example
MGB 2003 Reflection Dynamic Creation Example public static int Main(string[] args) { Type type1 = typeof(Test); //Instantiate the Test Object object[] ctorParams = new object[] (1); object obj = Adtivator.CreateInstance(type1, ctorParams); //Invoke a method object[] ctorParams = new object[] (3); int res = (int)type1.InvokeMember(“Amethod”, BindingFlags.Default|BindingFlags.InvokeMethod, null, obj.methodParams); return 0 } One very useful feature related to reflection is the ability to create objects dynamically and call methods on them. You can specify which class you want using a Type object, or by giving the name of an assembly and a class as stings, so this even makes it possible to get the name of a class from the user and create an object of the appropriate type. You can them interact with the new object just as if you’d created it with new, and use reflection to find out just what you’re dealing with and what it can do. This example shows how it works. The code creates an instance of our Test class, and invokes a method on the object. © 2003 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.

19 FieldInfo, PropertyInfo
MGB 2003 FieldInfo, PropertyInfo FieldInfo Field data type and attributes Static or Instance field, protection level Can set value through reflection Provides low-level, direct access with SetValueDirect() PropertyInfo Property type and attributes Test methods for readability, writeability "get" and "set" MethodInfo Indexer ParameterInfo Can invoke "set" and "get" through Reflection FieldInfo, PropertyInfo FieldInfo The FieldInfo class contains the member information for a certain field of a class (or structure) including its name and data type and attributes that have been declared on the field inside the structure of class. You will also be able to find out whether the field is an instance field or class field (static) and determine its protection level. Lastly, you can also manipulate a field’s value through Reflection, which is essential for tasks like interception in .NET Remoting. PropertyInfo The PropertyInfo provides you with detail information about a certain property. In addition to the information that is available for fields as discussed above, it also contains the method information for the associated “set” and “get” methods, parameter information if the property is an indexer and you are, of course, able to invoke the “set” and “get” methods directly through the PropertyInfo class. © 2003 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.

20 MethodInfo, ConstructorInfo
MGB 2003 MethodInfo, ConstructorInfo MethodInfo Return type and attributes List of all parameters as ParameterInfo array Detail implementation information through flag-field Can invoke method through Reflection ConstructorInfo Same features as MethodInfo, just for constructors MethodInfo, ConstructorInfo MethodInfo The MethodInfo class gives you all details about the signature, attributes and return values of a certain method. All parameter descriptions are accessible in order through the GetParameters() method and low-level details about the embedded IL code are available through a flag-field that can be obtained through a call to the method GetMethodImplementationFlags(). The method can also be invoked directly through the MethodInfo class, given an object to execute the call on. ConstructorInfo The ConstructorInfo class, derived from the same base class as MethodInfo (MethodBase), is very similar to the MethodInfo class, but reflects the very specialized initialization methods (constructors) for classes. These should not be called except at construction time and are therefore separated from the methods. © 2003 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.

21 Attributes Custom attributes are the killer-app for Reflection!
MGB 2003 Attributes Custom attributes are the killer-app for Reflection! Attributes enable declarative behavior Attributes allow data augmentation [dbcolumn("Address1")] string Street; [dbcolumn("Postcode")] string ZIP; Mark class as serializable Type.GetCustomAttributes() Map fields to database columns with FieldInfo.GetCustomAttributes() Custom attributes are the killer-app for Reflection! Custom attributes are the real killer application for Reflection and something that you should really consider looking at very closely. The Reflection features that we highlighted up to here, like all the detailed member information are certainly useful for implementing late-bound applications and for creating more solid code, but attributes indeed enable a whole new development paradigm: attribute-driven programming. Attributes enable declarative behavior Attributes are special elements (classes) in the .NET Framework that allow you to augment any structural element of .NET classes and structures with auxiliary information that is not immediately part of the class’s runtime behavior but serves to provide additional information that is either being evaluated by the runtime and the .NET Framework or your own frameworks. An example for this is the [serializable] attribute, which tells the Serialization framework that it is allowed to serialize a class’s state as-is and using the class Metadata for Remoting or persistent storage. If the attribute is not present, the class implementer essentially denies that permission and either provides an own implementation for serialization through the ISerializable interface or does not permit serialization and remote marshaling at all. As such, simple attributes will only be instantiated if they are explored via Reflection. They are indeed specifically created for this purpose. Attributes allow data augmentation Another possible use is the augmentation of data elements with additional hints. The shown example assumes a (imaginary) persistency framework that uses attributes as hints to match class fields to database columns. This is the type of information that had previously been expressed using macro-driven “maps”, which associate members with numbers or text expressions in frameworks like the ATL or MFC class libraries. With attributes, all this information can now be placed where it belongs: At the field declaration itself. [serializable] class Person { ... © 2003 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.

22 The Bigger picture Types know their Module, Modules know their types
MGB 2003 The Bigger picture Types know their Module, Modules know their types Modules know their Assembly and vice versa Code can browse and search its entire context Assembly Module Module Module Class Struct Delegate Types know their Module, Modules know their types Another strong point of the Metadata is that it allows navigating the entire context of a type. A module, reflected by the System.Reflection.Module class, knows all of the types it defines and implements and each types knows its implementing module. Modules know their Assembly and vice versa Likewise, all modules know and make their container assembly accessible and the assembly can list all modules it contains. Code can browse and search its entire context Finally, the Application Domain (AppDomain) class of the “current” application knows all loaded assemblies, so that you have a full information model about an application’s Metadata at any time and from wherever you need it. Constructor Class Class Method Interface Interface Method Field Class Interface © 2003 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.

23 The Unmanaged Spy: Metadata API
MGB 2003 The Unmanaged Spy: Metadata API Unmanaged (COM) Version of Reflection Used by VisualStudio.NET and Compilers Full Access to all Reflection Information for Tools Fully documented in the "Tool Developer's Guide" Buddy: Assembly Metadata API Reads/writes Assembly Manifests Unmanaged (COM) Version of Reflection While the Reflection API is accessible only from managed code, tool vendors that want to produce managed code applications from their IDEs or applications that want to interact with managed code may indeed be largely implemented in COM, like the initial release of Microsoft VisualStudio.NET. For these scenario, the .NET Framework provides an alternate implementation of the full functionality of the managed Reflection API as a COM version, which allows you to explore then content and full type information of managed code assemblies from within COM based applications. Used by VisualStudio.NET and Compilers VisualStudio.NET and the .NET compilers, which are mostly unmanaged code in their initial releases (one reason is that bootstrapping the entire environment in one step would be just too difficult in terms of complexity – even for Microsoft) use the COM based version of Reflection to reflect on and emit managed code. Full Access to all Reflection Information for Tools The COM “Metadata API” is in no way a second-class implementation, but has to be seen as a side-by-side sibling to the managed Reflection API. Fully documented in the "Tool Developer's Guide" The complete reference documentation for the “Metadata API” is located in the “Tool Developer’s Guide “portion of the Framework SDK and is automatically installed with the kit. Buddy: Assembly Metadata API The Metadata API’s “buddy” is the Assembly Metadata API, which is also documented in the Tools section and provides navigable access to the Assembly manifest and allows you to produce such manifests from code. © 2003 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.

24 Building Types at Runtime
MGB 2003 Building Types at Runtime Introducing System.Reflection.Emit Why? Some scenarios Dynamic Modules and Assemblies Creating Types and Classes Writing IL In this section we are going to cover “the other side” of Reflection, the “Emit” namespace. The informational and navigational capabilities of reflection are already fascinating, but the “Emit” namespace and its classes take this even a step further by enabling you to create .NET applications from within .NET programmatically and without having to go through the complexity of writing binary formats yourself. With this, System.Reflection.Emit is in fact democratizing automatic code generation and lets developers wanting to create code or Metadata from within their applications focus on just that and not on details of the operating system’s loaders. © 2003 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.

25 Introducing System.Reflection.Emit
MGB 2003 Introducing System.Reflection.Emit Full representation of physical structure Allows building modules and assemblies at runtime Transient code only used at runtime Persistent code for reuse Create classes, types and emit IL Used by .NET compilers to build .NET apps Full representation of physical structure The classes in the System.Reflection.Emit namespace reflect the entire physical and logical structure of an assembly and its embedded modules and types. Allows building modules and assemblies at runtime With this, you can create full functional assemblies and modules from within .NET managed code applications (or through the equivalent functionality in the COM Metadata API) at runtime. This allows you to create transient assemblies that reside only in memory for as long as the application is active and to create assemblies that you can persist into files and which can later be used just like any other assembly. Create classes, types and emit IL Inside any assembly’s modules you can create classes, types and emit code expressed in the Microsoft Intermediate Language (IL) for which you can find the full documentation and specifications in the Tool Developer Section of the Framework SDK. Used by .NET compilers to build .NET apps The .NET compilers and runtime components to generate .NET code use the “Emit” part of Reflection. Managed code uses the managed System.Reflection.Emit portion and unmanaged code uses the unmanaged COM API. © 2003 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.

26 Why? Some Scenarios… Build classes dynamically from script-like code
MGB 2003 Why? Some Scenarios… Build classes dynamically from script-like code ASP.NET, Regular Expressions do just that ! Generate code from visual development tools e.g. build interfaces, base classes from UML Create dynamic wrappers for existing code Transfer code-chunks to remote machines Distributed processing scenarios (like Why? Some Scenarios… So why would you want to generate code programmatically instead of writing C# (or any other language) code and compile it by “traditional” means? The list of scenarios is indeed endless and only limited by your imagination. The following is really just a very short collection of ideas what you could do: Build classes dynamically from script-like code You can use Reflection to create classes dynamically from script-like code. In .NET, the Regular Expression compilers is an actual example of a not-really-a-complete-programming-language programming language that scans and parses input text data and emits managed code directly from the parse tree via Reflection. If your application exposes user-definable formulas or scripting like features, you can use Reflection.Emit to turn these scripts into actual IL code and consequentially into machine code at execution time. Generate code from visual development tools If you use CASE-like tools that express class framework skeletons or even more in-depth specifications in, for instance, UML, you can write code generators that emit the full Metadata for the base classes that business-logic application developers must derive from to implement the logic using your own code-generators that read the UML (or XMI) model and produce the code via Reflection.Emit. Create dynamic wrappers for existing code You may also want to create dynamic wrappers for existing, unmanaged code. A tool that scans C header files or a COBOL copy-section and produces a managed code assembly that uses P/Invoke to interface with such existing code-bases could, for instance, produce such dynamic wrappers that let you leverage existing code-bases natively. Transfer code-chunks to remote machines Reflection.Emit can also be used in conjunction with Remoting to transfer and regenerate code on remote machines to execute tasks there. Possible scenarios for this include distributed numeric processing mirroring the project where the processing code could be sent along with the data payload and emitted and run at the destination. The .NET security model’s cascaded sand-boxing that let’s you control the permissions for any code that are calling prevents malicious use of these features. © 2003 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.

27 Building Assemblies System.Reflection.Emit.AssemblyBuilder
MGB 2003 Building Assemblies System.Reflection.Emit.AssemblyBuilder Dynamically create new assemblies Create manifest and resources Add modules Specify security requirements Can be persisted as files or held in memory Act and behave like any other assembly System.Reflection.Emit.AssemblyBuilder The AssemblyBuilder class is at the root of every “Emit” process in that it allows to create new assemblies, which are required to host modules and their classes and associated code. Dynamically create new assemblies The AssemblyBuilder will enable you to create the full manifest for an assembly, associate new modules and resources and specify attributes on the assembly like requested security permissions that apply when the assembly is loaded into an application domain. Can be persisted as files or held in memory, act and behave like any other assembly The AssemblyBuilder state may be saved into a file or just held in memory. If the state is saved, a full features Assembly file with all its subordinate modules is written to the requested location that is in no way different than the files produced by, for instance, the Visual C# compiler on disk or at runtime. © 2003 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.

28 Building Modules System.Reflection.Emit.ModuleBuilder
MGB 2003 Building Modules System.Reflection.Emit.ModuleBuilder Modules contain types, classes and code Allows creating fully functional modules with code Can associate source code Emit debug symbols Acts like any module created by any .NET compiler System.Reflection.Emit.ModuleBuilder The ModuleBuilder allows for the complete programmatic definition of a module, which is .NET’s concept of a code-container. Modules contain types, classes and code Modules contain types, classes and code for one or multiple namespaces including their intermediate language code. All of them can be built with the TypeBuilder, MethodBuilder, EnumBuilder classes and their siblings, which can all be created and accessed via the ModuleBuilder class. Allows creating fully functional modules with code The ModuleBuilder allows you to define complete, dynamic modules with all features. Not only can they contain type and class declarations and class implementations but you can also add advanced information that can be used for diagnostic purposes. Can associate source code You can, for instance, associate references to source code documents that were used to produce the output. Emit debug symbols Likewise, you can also emit full symbolic debug information and actually enable .NET debuggers to debug your applications although the code was generated based on your own custom language. Acts like any module created by any .NET compiler In the end, the Reflection.Emit produced modules can act exactly like any other module in terms of functionality. © 2003 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.

29 Writing IL Emit accepts IL (Intermediate Language) code
MGB 2003 Writing IL Emit accepts IL (Intermediate Language) code Same code as emitted by C#, VB.NET, Eiffel# IL is optimized and translated into machine code Reflection.Emit puts you "on-par" Same backend as .NET compilers Same access to code-generation Languages are mostly scanners and parsers For more info see System.CodeDOM Emit accepts IL (Intermediate Language) code The MethodBuilder exposes the method “GetILGenerator” which returns an instance of the ILGenerator classes that eases emitting IL code. The IL code is automatically associates with the method the generator was requested for. Same code as emitted by C#, VB.NET, Eiffel# Since all of the .NET compilers (with a partial exception being C++) produce IL as well, the output from this can be exactly the same as from any of these languages. IL is optimized and translated into machine code The IL is then optimized fro the target machine when it is translated into machine code by one of .NET’s JIT compilers. Reflection.Emit puts you "on-par" Essentially, Reflection.Emit can put you on par with all other development tools out there in that it makes code-generation more accessible, allows you to use the same optimizing back-ends as any other .NET compiler. In .NET programming languages are very smart and syntax aware scanners and parsers that can translate the expressions into terms of the IL. For more info see System.CodeDOM For more information on compiler support you should also take a look at the System.CodeDOM namespace. © 2003 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.

30 Putting It Together VisualStudio.NET and Reflection
What ASP+ really does with a page

31 VisualStudio.NET and Reflection
MGB 2003 VisualStudio.NET and Reflection Toolbox Component Class Description Properties Window DefaultValue Help Localizable Designers ReadOnly VisualStudio.NET is certainly the busiest user of Reflection to-date. By looking at the information available in the VisualStudio environment once a project has been loaded, it can easily be derived that VisualStuido.NET obtains a major portion of the information presented from all sorts of assemblies by ways of Reflection. This becomes indeed most obvious in the localized, non-English versions of VisualStudio.NET, since a large portion of the information indeed remains to be expressed in English, because it is pulled from Metadata. The Properties window for components or controls shown in the .NET designers will show browsable properties of .NET components based on attribute settings that it finds via Reflection. The component Metadata will also drive the way the designer windows that are hidden behind the “triple dot” (…) buttons are being launched and associated. The Toolbox window will know what can be displayed in the same way. Help ComponentModel Attributes © 2003 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.

32 What ASP.NET does with a Page
MGB 2003 What ASP.NET does with a Page IIS ASP.NET runtime assembly exists, same timestamp? file exists? 1 2 3 2a run no? compile <%Page codebehind="pg"%> <html> <body> <asp:label/> <asp:textbox/> </html> </body> ASP.NET compiler Page Assembly ASP.NET is also heavily relying on Reflection. The process for creating the ASP.NET assemblies that are executed at runtime can be quickly explained as follows: First the ASP.NET runtime will check whether a requested file does actually exist. The file to be checked for is the actual ASPX text file. Second it will check whether a matching compiled assembly exists that has the same timestamp as the text file. If this is not the case, the ASP.NET compiler will compile the file into a Page class (expressed in C# or the page language) and explores the code-behind assembly via Reflection to be able to match up the page expressions against the code-behind class. In a second step, it invokes the page language compiler to translate the code-generated Page into an assembly. The third step is to execute the Page class’ handling code and return the result to the client. Reflection class pg : Page { ... } © 2003 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.

33 Summary Reflection = System.Type + GetType()
MGB 2003 Summary Reflection = System.Type + GetType() Explore Type Information at Runtime Enables Attribute-Driven Programming Use Emit Classes to Produce .NET Assemblies Bottom Line: Fully Self-Contained Structural Model Reflection = System.Type + GetType() At the heart of Reflection are the method GetType() that is available on each and every object in .NET and the System.Type class that it returns. If you could only remember a single thing about Reflection, this should be it. Explore Type Information for everything at Runtime The System.Type class and the additional classes in the System.Reflection namespace that accessible through it let you explore every structural element of .Net applications at runtime without extra effort at development or compile time. Enables Attribute-driven programming Reflection also enables the powerful Attribute-driven programming model that lets you add declarative behavior to code. Use Emit Classes to Produce .NET Assemblies You can use the System.Reflection.Emit namespace classes to create .NET Assemblies in much the same way as the .NET toolsets do it. Bottom line: Fully Self-Contained Structural Model To sum it all up: With Reflection, .NET provides and contains an entirely self-describing and self-contained structural model that does not require any external tools to create .NET compliant components. © 2003 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.


Download ppt "Q Reflection Nauzad Kapadia MGB 2003"

Similar presentations


Ads by Google