240 likes | 328 Views
Attributter og Reflection. Kilde: Joe Hummel, kursus i .Net, jan. 2003. Content.
E N D
Attributter og Reflection Kilde: Joe Hummel, kursus i .Net, jan. 2003
Content “For some years, Microsoft's development tools have embraced a declarative programming style — programmer's declare their intent ("I need a database transaction"), and the underlying software provides the implementation ("BeginTrans … Commit"). .NET has formalized this style of programming in the form of attributes (declaring intent) and reflection (recognizing intent)…” • Attributes • Reflection
Part 1 • Attributes… Not to be confused with the attributes of a class!
Attributes • Attributes is a general mechanism for outlining code • To support declarative programming • Be able to develop .NET in unforeseen directions • We can define our own attributes • .NET contains many predefined attributs for: • Transaction handling • Serialization • COM interaction • Version control and ‘digital signing’ of the assembly
Where are attributes used? • Many technologies in .NET uses attributes: • CLR • ASP.NET • C# compiler • Visual Studio .NET
Attributes example • Attributes are used for example in a webservice • Example: • By specifying a method as [WebMethod], it turns into a web service in .NET public class Service1 : System.Web.Services.WebService { [WebMethod] public int Add(int x, int y) { return x + y; } . . . } attribute
Objekt serialisation • Add the System.Serializable() attribute and . NET offers support for serialisation • Here an object is serialized to an XML-file… [ System.Serializable() ] public class Person { public string name; public int age; . . . using System.Runtime.Serialization.Formatters.Soap; using System.IO; Person p; p = new Person(...); FileStream fs = new FileStream(@"C:\person.xml", FileMode.Create, FileAccess.Write); SoapFormatter formatter = new SoapFormatter(); formatter.Serialize(fs, p); // serialize to XML! fs.Close();
Another example • Conditional compiling is a good tool for debugging • in DEBUG mode, assert / collect / emit debug info • in RELEASE mode, disable the debug things • In the old fashion C way by using #if directives: public class MyClass { #if DEBUG private void DebugInfo() { << output debug info to screen, file, or ... >> } #endif public void MyMethod() { #if DEBUG this.DebugInfo(); #endif . . .
Conditional compiling, the .NET way • The .NET way used the Conditional attribute: • methods is included if the symbol is defined • Calls are made if the symbol is defined public class MyClass { [ System.Diagnostics.Conditional("DEBUG") ] private void DebugInfo() { << output debug info to screen, file, or ... >> } public void MyMethod() { this.DebugInfo(); // call made only if DEBUG defined . . .
Custom attributes • .NET can be extended with your own attributes • Example: • a database with a bug reporter: bug #, dato, symptom • when the error is corrected, assign an attribute in the source with developer id and bug # • write an app in C# for generating a rapport about: • unresolved bugs • error corrections pr. person • error corrections in chronological order • etc.
BugFix attributten • Inside the program attributes are just classes (like everything else :-) [ AttributeUsage(AttributeTargets.All, AllowMultiple=true, Inherited=false) ] public class BugFixAttribute : System.Attribute { public int BugNumber; public string Author; public DateTime TheDate; // constructor public BugFixAttribute(int BugNumber, string Author, string DateStr) { this.BugNumber = BugNumber; this.Author = Author; this.TheDate = System.Convert.ToDateTime(DateStr); } }
Brug af BugFix • Programmører kommenterer kode efterhånden som fejlrettelser implementeres… [ BugFix(4423, "Jim Bag", "1 April 2002"), BugFix(5518, "Jane Doe", "28 June 2002") ] public class MyClass { public MyClass() { . . . } [ BugFix(3004, "Kim Lee", "1 January 2002") ] public void SomeMethod() { . . .
Where are attributes stored? • Attributes are stores inside the assembly as metadata Component.dll Assembly Manifest assembly-specific metadata [ AssemblyVersion("1.0.0.0") ] Type Information MyClass metadata [ Serializable() ] Method1 metadata [ BugFix(...) ]
How find attributes? • Through reflection…
Part 2 • Reflection…
System.Object Assembly AssemblyName MemberInfo ParameterInfo System.Type MethodBase FieldInfo PropertyInfo EventInfo MethodInfo ConstructorInfo Reflection • Reflection: to read metadata • With the reflection classes in FCL makes you able to reflect on classes • reflection library is in the System.Reflection namespace • compiled into the mscorlib.dll assembly
Who uses reflection? • Tool builders • Microsoft .NET: • CLR • ASP.NET • C# compiler • Visual Studio .NET
Example • Fetch an assembly and look for BugFix attributes • 3 steps: • Get the assembly is necessary. • Get information about each type (class) in the assembly • Look for the BugFix attribute…
Step 1: Get the assembly • There are different ways to retrieve the assembly for reflection: using System.Reflection; Assembly asm; string asmName = ...; // e.g. "Component" string fileName = ...; // e.g. @"C:\Bin\Component.dll" asm = Assembly.GetExecutingAssembly(); // (1) current asm asm = Assembly.Load(asmName); // (2) load by name asm = Assembly.LoadFrom(pathName); // (3) load by file name <cont'd on next page…>
Step 2: Get the types • When the assembly is loaded it is easy to get the types: Type[] types; types = asm.GetTypes(); // get types from assembly Type attribute; attribute = Type.GetType("BugFixAttribute, BugFixAssembly"); foreach (Type t in types) { . . . <cont'd on next page…>
Step 3: Look for BugFix attributes • Look at each type, as well as members of each type… private void process(object[] attributes) { foreach (BugFixAttribute bugfix in attributes) MessageBox.Show(bugfix.Author); } object[] attributes; MemberInfo[] members; foreach (Type t in types) { attributes = t.GetCustomAttributes(attribute, false); process(attributes); members = t.GetMembers(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static); foreach (MemberInfo m in members) { attributes = m.GetCustomAttributes(attribute, false); process(attributes); } }
How strong is reflection? • Try these tools: • FxCOP: checks assembly against design rules • Anakrino: reverse engineering assembly —> C# • Other possibilities: • dynamic call of methods (e.g. plugins) • dynamic generation of code (System.Reflection.Emit)
Summary • Attributes and reflection are strong concepts • declarative programming style • can be extended in subsystems • widely used in .NET…
References • Books: • S. Lippman, "C# Primer" • J. Richter, "Applied Microsoft .NET Framework Programming" • Web sites: • FxCOP: http://www.gotdotnet.com/team/fxcop/ • Anakrino: http://www.saurik.com/net/exemplar/