1. Trang chủ
  2. » Công Nghệ Thông Tin

Beginning Microsoft Visual C# 2008 PHẦN 9 docx

135 296 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề Beginning Microsoft Visual C# 2008 Part V: Additional Techniques
Trường học University of Microsoft
Chuyên ngành Computer Science
Thể loại Sách hướng dẫn
Năm xuất bản 2008
Thành phố Redmond
Định dạng
Số trang 135
Dung lượng 1,96 MB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

XML documentation enables you to include syntax, help, and examples for the classes you create at the source - code level.. For example, the following code shows how to place XML docume

Trang 1

A similar method is used to set the Inherited property If a custom attribute has properties, then you

can set these in the same manner One example might be to add the name of the person who fixed

the bug:

public readonly string BugNumber;

public readonly string Comments;

public readonly string Author;

return string.Format (“BugFix {0} by {1} : {2}” ,

BugNumber , Author , Comments);

}

This adds the Author field and an overridden ToString() implementation that displays the full details

if the Author field is set If the Author property is not defined when you attribute your code, then the

output from the BugFix attribute just shows the bug number and comments The ToString() method

would be used to display a list of bug fixes for a given section of code — perhaps to print and file away

somewhere Once you have written the BugFix attribute, you need some way to report the fixes made

on a class and the members of that class

The way to report bug fixes for a class is to pass the class type (again a System.Type ) to the following

DisplayFixes function This also uses reflection to find any bug fixes applied to the class, and then

iterates through all methods of that class looking for BugFix attributes:

public static void DisplayFixes (System.Type t)

{

// Get all bug fixes for the given type,

// which is assumed to be a class

object[] fixes = t.GetCustomAttributes (typeof (BugFixAttribute) , false);

Console.WriteLine (“Displaying fixes for {0}” , t);

// Display the big fix information

foreach (BugFixAttribute bugFix in fixes)

Console.WriteLine (“ {0}” , bugFix);

// Now get all members (i.e., functions) of the class

foreach (MemberInfo member in t.GetMembers (BindingFlags.Instance |

BindingFlags.Public |

BindingFlags.NonPublic |

BindingFlags.Static))

{

// And find any big fixes applied to these too

object[] memberFixes = member.GetCustomAttributes(typeof(BugFixAttribute)

, false);

if (memberFixes.Length > 0)

{

Trang 2

Console.WriteLine (“ {0}” , member.Name);

// Loop through and display these

foreach (BugFixAttribute memberFix in memberFixes) Console.WriteLine (“ {0}” , memberFix);

} }}

The code first retrieves all BugFix attributes from the type itself:

object[] fixes = t.GetCustomAttributes (typeof (BugFixAttribute),false);

These are enumerated and displayed The code then loops through all members defined on the class, by using the GetMembers() method:

foreach (MemberInfo member in t.GetMembers ( BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static))

After getting all members, you loop through these, finding any BugFix attributes associated with the particular member, and output these to the console To output a list of bug fixes for a given class, you just call the static DisplayFixes() method, passing in the class type:

BugFixAttribute.DisplayFixes (typeof (MyBuggyCode));

For the MyBuggyCode class presented earlier, this results in the following output:

Displaying fixes for MyBuggyCode BugFix 101 : Created some methods DoSomething

BugFix 2112 : Returned a non-null string BugFix 38382 : Returned OK

.ctor BugFix 90125 : Removed call to base()

If you wanted to display fixes for all classes in a given assembly, you could use reflection to get all the types from the assembly, and pass each one to the static BugFixAttribute.DisplayFixes method

Trang 3

AttributeUsage.Inherited

An attribute may be defined as inheritable by setting this flag when defining the custom attribute:

[AttributeUsage (AttributeTargets.Class,

Inherited = true)]

public class BugFixAttribute { }

This indicates that the BugFix attribute will be inherited by any subclasses of the class using the

attribute, which may or may not be desirable In the case of the BugFix attribute, this behavior would

probably not be desirable, because a bug fix normally applies to a single class and not the derived

classes

Suppose you have the following abstract class with a bug fix applied:

[BugFix(“38383”,”Fixed that abstract bug”)]

public abstract class GenericRow : DataRow

If you created a subclass from this class, you wouldn ’ t want the same BugFix attribute to be reflected in

the subclass — the subclass has not had that fix done on it However, if you were defining a set of

attributes that linked members of a class to fields in a database table, then you probably would want to

inherit these attributes

Armed with the knowledge you now have about custom attributes, you can probably think of several

places where adding extra information to assemblies is useful You could take the BugFix attribute

defined here and extend it too — one example would be to define the version number of the software

that the bug was fixed in That would enable you to display to end users all bugs fixed for a given

version of your application simply by using reflection to find the BugFix attributes and then checking

the version number of that fix against the versions that the end user has asked to see

This would also be great for producing documentation at the end of a product cycle to list all fixes made

in the latest version Obviously, you have to rely on the developers to add in these attributes, but it could

be made part of the code review cycle to ensure that all fixes were documented within the code

Summar y

This chapter described what attributes are and discussed some of the attributes defined within the NET

Framework There are many more attribute classes within the framework, and the best way to find out

what they are used for is to look through the NET Framework SDK documentation To find all attributes

in an assembly, just load it into Reflector, browse for the System.Attribute class, and then display the

derived types You may be surprised at just how many attributes are defined within NET

Trang 4

In this chapter, you learned about the following attribute - related topics:

Using the Conditional attribute to exclude debugging code from release mode binaries Using the Obsolete attribute to revise libraries over time

How serialization uses attributes to specify what should and what should not be serialized How to delay - sign an assembly

How to create custom attributes

Attributes are a powerful way to add extra, out - of - band information to your assemblies You can create your own attributes to add extra information to your classes as appropriate This chapter described how

to create a BugFix attribute, which could be used to provide a link between the source code that was fixed and the bug originally raised by an end user There are many other uses of attributes — and you are encouraged to look into the NET Framework for other attribute classes

Trang 6

31

XML Documentation

Up to this point in this book, you ’ ve seen the entire C# language and a great many things you can

do with it, including both Web and Windows programming Along the way, you ’ ve seen and made extensive use of the IntelliSense feature in Visual Studio This helpful tool dramatically reduces the amount of typing you have to do, because it suggests keywords, type names, variable names, and parameters as you type It also makes it easier to remember what methods and properties you have at your disposal and often tells you exactly how to use them

However, the classes you have made have suffered slightly here While the classes and member names are suggested for you, no handy hints pop up telling you how to do things To achieve the

kind of behavior that you see with the NET Framework types, you need to use XML

documentation XML documentation enables you to include syntax, help, and examples for the

classes you create at the source - code level This information may then be used to provide IntelliSense information for Visual Studio as discussed previously, but there are other possibilities

You can use XML documentation as a starting point for full, MSDN - link documentation of your projects You can also style the XML documentation using XSLT to obtain instant HTML documentation with very little effort You have seen in earlier chapters just how versatile XML is, and you can use all of its power in the development and production life cycle of your applications

Documentation is particularly important when you are working as part of a team, as it enables you

to show exactly how your types work It can also be very useful to end users if you are creating an SDK or similar product where you expect people to use your classes from their code Having the facility to create this documentation built into the tool you use to develop code is a very powerful feature Although adding XML documentation to your code can be a time - consuming process, the result is well worth it Dropping text in as you develop can make things easier in the long run and provide you with a handy quick reference that will help to avoid confusion when the amount of classes in your project starts getting out of hand

In this chapter, you will learn two main things:

How to add and view basic XML documentation How to use XML documentation

Trang 7

Adding XML Documentation

Adding XML documentation to your code is a remarkably simple thing to do As with attributes, which

you examined in the previous chapter, you can apply XML documentation to any type or member by

placing it on lines just before the member XML documentation is added by using an extended version of

C# comment syntax, with three front slashes instead of two For example, the following code shows how

to place XML documentation in a source code file for a class called MyClass , and a method of that class,

XML documentation cannot be applied to namespace declarations

Typically, XML documentation will span multiple lines and be marked up by using the XML

Here, < XMLDocElement > is one of several available elements, and may contain nested elements, some

of which use attributes to further specify functionality Note that the /// parts of the lines of code

containing XML documentation are completely ignored and treated as whitespace They are necessary to

prevent the compiler from thinking that the lines of documentation can be interpreted as code, which

would lead to compiler errors

The most basic element for XML documentation is < summary > , and it provides a short description of a

type or member Before moving on to anything more complicated, you should take a look at the

following example, which illustrates this element and how the results become visible

Try It Out Adding and Viewing Basic XML Documentation

1 Create a new console application called FirstXMLDocumentation and save it in the directory

C:\BegVCSharp\Chapter31

2 Add a class called DocumentedClass

Trang 8

3 Open the code for DocumentedClass , make the class definition public, add a new line before the class declaration, and type /// (three forward slashes)

4 Note that the IDE auto - completion adds the following code, placing the cursor inside the

< summary > element:

namespace FirstXMLDocumentation{

Trang 9

7 Open the Object Browser widow and expand the entry for the FirstXMLDocumentation

project until you can click DocumentedClass Note the summary information displayed in

the bottom - right pane, as shown in Figure 31 - 2

Figure 31-2

How It Works

This example demonstrates the basic technique for adding XML documentation and how this

documentation is used in the IDE When adding the basic summary information for your

DocumentedClass class, you saw how the IDE dynamically detects what you have in mind and fills

out the basic code for you IntelliSense and the Object Browser detect the documentation you added

without even having to compile the project These basic techniques apply to all aspects of XML

documentation and make it easy to add and consume this information

XML Documentation Comments

You can in fact add any XML you like to the XML documentation of a target (by target we mean type or

member ) However, some recommended elements and attributes will help your documentation to meet

standard guidelines The recommended XML is enough for most situations, and following this standard

means that tools that consume XML documentation (including IntelliSense and the Object Browser) can

interpret your documentation effectively

Brief descriptions of the basic elements for XML documentation are shown in the following table You ’ ll

look at each of these in more depth in subsequent sections

Trang 10

< item > Represents an item in a list Used as a child of < list > , and can have

< description > and < term > children

< list > Defines a list Can have < listheader > and < item > children

< listheader > Represents the header row of a tabular list Used as a child of < list > , and

can have < description > and < term > children

< seealso > References another target, usually used outside of other elements, or at the

end of, for example, < summary >

< summary > Holds summary information concerning the target

< term > Marks text as being an item definition Used as a child element of < item > or

Trang 11

Text Formatting Elements

Many of the elements shown in the preceding table are intended for formatting the text within other

elements A < summary > element, for example, might contain a combination of other elements that

specify the text to display The text formatting elements are < > , < code > , < list > , and its associated

elements, < para > , < paramref > , and < see > < seealso > is a special case that you can also include in this

list, as it can be included in a body of text, although it usually occurs at the end

< para >

The < para > element is used to separate text into paragraphs:

/// < summary >

/// < para > 1st paragraph of summary < /para >

/// < para > 2nd paragraph of summary < /para >

/// < /summary >

< c > and < code >

The < > and < code > elements are both used to format text in a code font, typically a monospaced font

such as Courier The difference is that < > can be thought of as “ code in text, ” that is, code words that

appear in the middle of sentences, whereas < code > is used for sections of code outside of text < > and

< code > might be used as follows:

< see > , < seealso > , < paramref > , and < typeparamref >

These four elements are all used to refer to other entries in the XML documentation for a project or to

external MSDN entries Commonly, each of these will be rendered as a hyperlink, enabling

documentation browsers to jump to other entries

< see > and < seealso > specify their target via a cref attribute, where the target can be any type or

member of any class, in the project or elsewhere < paramref > and < typeparamref > use a name

attribute to reference a parameter of the current target:

/// < summary >

/// < para >

/// This method uses < paramref name=”museName” / > to choose a muse

/// For more details, see < see cref=”MyPoet” / >

/// < /para >

/// < seealso cref=”MyParchment” / >

/// < seealso cref=”MyTheme” / >

/// < /summary >

Trang 12

Note that the elements don ’ t include the text to display, which will typically be constructed from the

name , cref , or langword attribute You should bear this in mind to avoid repetition of text, for example:

/// This method uses < paramref name=”museName” / > museName to choose a muse

Here the word museName is likely to be repeated

< list > and Associated Elements

The < list > element is the most complicated text formatting element because it can be used in different ways It has an attribute called type that can be any of the following:

bullet — Formats a bulleted list number — Formats a numbered list table — Formats a table

A < list > element typically has a single < listheader > element child and several < item > children

Each of these may have < term > and < description > children The exact choice of which children to use will depend on the type of the list and the way your chosen tool formats lists < term > , for example, is optional in table format lists, while < listheader > might make sense only in a table For bulleted lists you could use something like the following:

/// < term > Muse name < /term >

/// < description > Muse’s favorite pizza < /description >

/// < /listheader >

/// < item >

/// < term > Calliope < /term >

/// < description > Ham & amp; Mushroom < /description >

/// < /item >

/// < item >

/// < term > Clio < /term >

/// < description > Four Seasons < /description >

/// < /item >

Trang 13

/// < item >

/// < term > Erato < /term >

/// < description > Meat Feast < /description >

/// < /item >

/// < /list >

/// < /para >

/// < /summary >

Because the exact behavior of the formatting with these elements may vary, it ’ s best to experiment a bit

Note that whatever you do with these elements, you won ’ t see any difference in the Object Browser,

which ignores them

Major Structural Elements

Several of the elements in the previous table are intended for use as top - level elements in the description

of a given target < summary > is a good example of this, as you saw in the earlier example The < summary >

element should never be contained in another element, and it is always used to provide summary

information about the target The other elements that fit this description are < example > , < exception > ,

< param > , < permission > , < remarks > , < returns > , and < value > < seealso > is a special case that

can be either a top - level element or a child of another element < include > is another special case,

because it effectively overrides other elements by fetching XML from an external file

You ’ ll look at each of these elements in turn

< summary > , < example > , and < remarks >

Each of these three elements provides general information about the target You ’ ve already seen

< summary > , which you can use to provide basic information about a target Because this information

appears in tooltips, it ’ s a good idea to keep this information short; put additional information in

< example > and < remarks >

Often when you are introducing a class, it can be helpful to give an example of how that class should be

used The same applies to methods, properties, and so on Rather than include this information in

< summary > , it can make sense to separate it into a new section, < example > :

Trang 14

Similarly, < remarks > is often used to provide a longer description of a target, and it may include more

< see > and < seealso > elements for cross - referencing

< param > and < typeparam >

These elements describe a parameter, either a standard method parameter or a type parameter, for generic targets The parameter being referenced is set by using a name attribute These elements may occur several times if several parameters are used, as shown here:

< returns > and < value >

These two elements are similar in that they both refer to a return value: < returns > is used for the return value for methods, and < value > is used for the value of a property, which can also be thought of as a return value Neither of these elements uses any attributes

For methods, you might use < returns > as follows:

Trang 15

< permission >

This element is used to describe the permissions associated with a target Actually setting the

permissions is performed by other means, such as applying a PermissionSetAttribute attribute to a

method; the < permission > element merely enables you to inform others about these permissions

The < permission > element includes a cref attribute, so you can, if you wish, reference a class that

includes additional information, such as System.Security.PermissionSet Here is an example:

/// < permission cref=”System.Security.PermissionSet” >

/// Only administrators can use this method

/// < /permission >

< exception >

This element is used to describe any exceptions that might be thrown during the use of the target It has

a cref attribute that you can use to cross - reference an exception type You might, for example, use this

element to state the range of allowed values for a property, and what would happen if someone

attempted to set the property to a value that isn ’ t allowed:

As previously mentioned, you can use the < seealso > element as a top - level element You can use

several of these, which, depending on the tool you use, may be formatted as a list of references at the end

of an entry for a target:

Including a lot of XML documentation in your source files can get a little messy, and you might want to

consider placing it in completely separate files This can also be desirable, for example, if someone else is

providing the documentation for your code, as you don ’ t have to give that person access to the source

files themselves

The < include > element enables you to do this, via its two attributes, file and path file specifies the

external XML file that contains the XML documentation you want to include, and path is used to locate

the specific section of XML within the document by using XPath syntax

Trang 16

For example, you could reference some external XML as follows:

/// < include file=”ExternalDoc.xml” path=”documentation/classes/MyClass/*” / > public class MyClass

Here a file called ExternalDoc.xml is referenced This may contain code such as the following:

public class MyClass

Adding XML Documentation Using a Class Diagram

In Chapter 9 , you were introduced to class diagrams, and since then you ’ ve seen how you can use class diagrams to create classes diagrammatically, with changes reflected in your code in real time You ’ ve also learned how to add classes and members, modify the signatures of methods, and so on It should, therefore, come as no surprise that you can use class diagrams to add XML documentation to your classes, without getting bogged down in source code

Recall that class diagrams are available only in VS, and are not included in VCE You need VS in order

to work through this example

Unfortunately, as you will see, adding XML documentation in this way isn ’ t as flexible as adding it manually, but you do get the advantage of being able to do things very quickly, without having to remember any XML syntax

You ’ ll see the capabilities in the following Try It Out

Trang 17

Try It Out Adding XML Documentation in a Class Diagram

1 Create a new class library application called DiagrammaticDocumentation and save it in the

directory C:\BegVCSharp\Chapter31

2 When the project has loaded, click the View Class Diagram button in the Solution Explorer

window You should see a diagram containing just the Class1 class that is generated for

you when you create a class library application

3 Add a class called DocumentedClass and modify its members as shown in Figure 31 - 3 and

the following table

Figure 31-3

Member Type Name Type Modifier Summary

Method GetFactors long[] public Gets the factors of a number

Property IncludeOne bool public Include 1 in GetFactors()

result Property IncludeSelf bool public Include self in GetFactors()

result

Trang 18

4 Click in the Summary box for the GetFactors() method, and then click the (ellipses) button Modify the text in the Description dialog as shown in Figure 31 - 4 and the following table

Figure 31-4

Field Value

Summary Gets the factors of a number Returns Returns a long array Remarks This method is used to obtain the factors of a number — that is, all the numbers that

the number can be divided by without leaving a remainder

If IncludeOne and IncludeSelf are both true and the result returned consists of exactly two numbers (the number itself and one), then the number is prime

5 Similarly, modify the Value and Remarks text for the IncludeOne and IncludeSelf properties, as shown in the following table:

Property Value Text Remarks Text

IncludeOne A bool value If this property is set to true , then GetFactors() will

include 1 in its long[] result

IncludeSelf A bool value If this property is set to true , then GetFactors() will

include its numberToFactor parameter in its long[] result

Trang 19

6 Click the class in the class diagram, and in the properties for the class, modify the Summary

and Remarks for the class as shown in the next table:

This class enables you to factorize a number

according to certain rules

Use GetFactor() to factorize a number according

to the rules defined by the IncludeOne and

IncludeSelf properties

7 Examine the code for DocumentedClass You should see the XML comments you have added

in place, such as the following:

/// < summary >

/// Gets the factors of a number

/// < /summary >

/// < remarks > This method is used to obtain the factors of a number, that is, all

/// the numbers that the number can be divided by without leaving a

/// < param name=”numberToFactor” > The number to factor < /param >

/// < returns > Returns a long array < /returns >

public long[] GetFactors(long numberToFactor)

{

throw new System.NotImplementedException();

}

How It Works

This example demonstrates how you can use a class diagram to set the XML documentation for a

project After reading the preceding section, you may be wondering why you haven ’ t included cross

references between methods and the like For example, why wasn ’ t the Remarks text for

GetFactors() set as follows:

This method is used to obtain the factors of a number, that is, all the

numbers that the number can be divided by without leaving a remainder

If < see cref=”IncludeOne” / > and < see cref=”IncludeSelf” / > are both < see

langword=”true” / > and the result returned consists of exactly two numbers

(the number itself and one) then the number is prime

The reason is because the text editor in the class diagram automatically escapes text that is entered

into the Description dialog, so the result of entering the previous code is actually the following:

/// < summary >

/// Gets the factors of a number

/// < /summary >

/// < remarks > This method is used to obtain the factors of a number, that is, all

/// the numbers that the number can be divided by without leaving a remainder

Trang 20

/// If & lt;see cref=”IncludeOne” / & gt; and & lt;see cref=”IncludeSelf” / & gt; are/// both & lt;see langword=”true” / & gt; and the result returned consists of exactly/// two numbers (the number itself and one) then the number is prime < /remarks > /// < param name=”numberToFactor” > The number to factor < /param >

/// < returns > Returns a long array < /returns >

public long[] GetFactors(long numberToFactor){

throw new System.NotImplementedException();

}

This is unfortunately one of the inconveniences you have to cope with if you add XML documentation

by using a class diagram It ’ s great for adding text, but to embed XML documentation markup, you have to modify the code manually

Generating XML Documentation Files

So far, all the XML documentation you have added has been confined to the development environment while you are working with a project If you want to actually do anything with the documentation you add, you have to set the project to output the documentation as an XML file

To do this, you need to modify the build settings for your project, as shown in Figure 31 - 5

Trang 21

The only changes to make are to check the XML Documentation File box and supply an output filename

It is generally a good idea to save the XML documentation file in the same directory as the assembly

because that is where the IDE searches for it If you have a client application to a documented assembly

in a different solution, you get the benefits of IntelliSense and help in the Object Browser only if the IDE

can find the XML documentation file

Once the build setting for XML documentation is turned on, the compiler will be configured to actively

search for XML documentation in your classes While it isn ’ t necessarily an error to omit XML

documentation for a given class or method, the IDE will alert you to anything missing, in the form of

warnings in the Error List window An example is shown in Figure 31 - 6

Figure 31-6

This warning, obtained from the previous example, indicates that documentation is missing for the

Class1 class (which you left unchanged)

Here ’ s the XML documentation file created for the previous example:

< remarks > Use GetFactor() to factorize a number according to the rules

defined by the IncludeOne and IncludeSelf properties < /remarks >

This method is used to obtain the factors of a number, that is, all the

numbers that the number can be divided by without leaving a remainder

If IncludeOne and IncludeSelf are both true and the result returned

consists of exactly two numbers (the number itself and one) then the

number is prime

< /remarks >

< returns > Returns a long array < /returns >

< /member >

Trang 22

< member name=”P:DiagrammaticDocumentation.DocumentedClass.IncludeOne” >

< summary >

Include 1 in GetFactors() result

< /summary >

< remarks > If this property is set to true, then GetFactors() will include

1 in its long[] result < /remarks >

< value > A bool value < /value >

This document contains the following:

A root level < doc > element containing all other documentation information

An < assembly > element containing a < name > element containing the name of the assembly to which the XML documentation applies

A < members > element containing the XML documentation for each member in the assembly Several < member > elements, each with a name attribute stating to which type or member the XML documentation contained by the < member > element applies

The name attributes of the < member > elements follow a consistent naming scheme They are all names belonging to one of the following namespaces — that is, they all start with one of the following letters:

T — Specifies that the member is a type (class, interface, strut, enumeration, or delegate)

M — Specifies that the member is a method

P — Specifies that the member is a property or indexer

F — Specifies that the type is a field or enumeration member (not shown in the example)

E — Specifies that the member is an event (not shown in the example) Any errors in the XML documentation for a type are shown in the generated file as a commented

< member > element:

< ! Badly formed XML comment ignored for member “T:DiagrammaticDocumentation.DocumentedClass” >

Within a < member > element, the XML documentation for a target is inserted exactly as is (unless there is

a problem with the XML)

Trang 23

Example Application with XML Documentation

For the remainder of this chapter, you ’ ll look at ways to use XML documentation files; and to make this

easier, you ’ ll be using a fully functional example class library called DocumentedClasses, which comes

packed with XML documentation of almost all types

The classes in the DocumentedClasses library are shown in Figure 31 - 7

Figure 31-7

The idea behind this class library is that a client application can create an instance of a Garden class and

then add instances of classes derived from GardenContent to the garden This can then be used to

obtain a simple graphical representation of the garden The classes effectively form a very basic garden

design tool

The downloadable code for this chapter includes this class library, should you want to investigate the

code for yourself, but there is no real need to present it all here Also included in the downloadable code

is a simple client application called DocumentedClassesClient, with code as follows:

static void Main(string[] args)

Trang 24

for (int y = 0; y < gardenDepth; y++) {

for (int x = 0; x < gardenWidth; x++) {

Console.Write(plan[x, y]);

} Console.WriteLine();

} Console.ReadKey();

}

This illustrates how to use the classes in DocumentedClasses, and results in the output shown in Figure 31 - 8

Figure 31-8

Trang 25

As you can see, very basic indeed! (Luckily, if you are a garden designer, there are better tools available.)

Of course, here you are merely interested in the XML documentation contained in DocumentedClasses

Making Use of XML Documentation

This chapter has mentioned in several places that there is much more that you can do with XML

documentation than simply use it to supply IntelliSense information to the IDE — which isn ’ t to say that

customized IntelliSense isn ’ t an extremely useful feature

Perhaps the simplest thing you can do with XML documentation is ship it with your assemblies and

leave it up to other people to make use of it, but this is far from ideal In this section, you look at some of

the possibilities for getting the most out of your documentation

Programmatically Processing XML Documentation

The most obvious thing to do with XML documentation is to make use of the wealth of XML tools in the

.NET namespaces Using the techniques and classes you saw in Chapter 25 , it is possible to load XML

documentation into an XmlDocument object The following Try It Out is a simple console application that

does just that

This Try It Out requires the XML documentation output from the example project, DocumentedClasses

Before starting this Try It Out, download and build the DocumentedClasses solution

Try It Out Processing XML Documentation

1 Create a new console application called XMLDocViewer in the directory

3 Modify the code in Main() as follows:

static void Main(string[] args)

{

// Load XML documentation file

XmlDocument documentation = new XmlDocument();

Trang 26

XmlNodeList memberNodes = documentation.SelectNodes(“//member”);

// Extract < member > elements for types

List < XmlNode > typeNodes = new List < XmlNode > ();

foreach (XmlNode node in memberNodes) {

if (node.Attributes[“name”].Value.StartsWith(“T”)) {

typeNodes.Add(node);

} } // Write types to the console

Console.WriteLine(“Types:”);

foreach (XmlNode node in typeNodes) {

Console.WriteLine(“- {0}”, node.Attributes[“name”].Value.Substring(2)); }

Console.ReadKey();

}

4 Execute the application The result is shown in Figure 31 - 9

Figure 31-9

How It Works

This example demonstrates the basics of loading and processing an XML documentation file in C#

code You start by loading in a documentation file, which in this case is the one generated by the DocumentedClasses type library:

XmlDocument documentation = new XmlDocument();

Trang 27

When you have a list of < member > elements, you can search through them, looking for those that start

with a T to get the elements that refer to types, and placing them into a List < XmlNode > collection:

List < XmlNode > typeNodes = new List < XmlNode > ();

foreach (XmlNode node in memberNodes)

You could, of course, achieve this in a single step using a more advanced XPath expression that

included an attribute check, but why overcomplicate things? Finally, you output the names of the

types found to the console:

There ’ s a lot more that you could do here, as navigating and processing XML files in NET isn ’ t a

complicated process However, because there are better ways of handling XML documentation, as

you ’ ll see in the next two sections, there is no real need to take this example further

Styling XML Documentation with XSLT

Because XML documentation is, by definition, XML, there is plenty of scope for using XSLT

transformations to convert your XML into HTML, or even to use XSLT formatting objects to create

printable documentation

At this point, we ’ d like to defer to the true master of (and driving force behind) C# — Anders Hejlsberg

He has published an XSLT document and associated CSS file to turn XML documentation files into

stylish HTML These two files, doc.xsl and doc.css , can be found in the downloadable code for this

chapter in the directory XSLTStyledXMLDocumentation In order to use these files, simply add a

processing directive to your XML documentation files as follows:

Trang 28

You ’ ll also find a version of DocumentedClasses.xml in the XSLTStyledXMLDocumentation directory that includes this directive A sample of the result is shown in Figure 31 - 10

Figure 31-10

The styling isn ’ t perfect — < seealso > elements in particular don ’ t come out right, and you can see

in the screenshot that there are problems with < code > formatting — but overall it ’ s pretty impressive The files make an excellent starting point should you wish to make a Web page of your documentation

The way that the < see > elements link to anchors on the page is particularly good

Perhaps the biggest problem with doing things this way is that everything appears in a single HTML page, which could get very large indeed

Documentation Tools

An alternative way of processing XML documentation is to use a tool Until recently, the tool of choice for XML documentation styling was NDoc NDoc is a third - party tool that is capable of converting your documentation into a number of formats, including MSDN - style help files Unfortunately, development

on NDoc is (at the time of writing) stalled

To obtain the most recent version of NDoc (which is free), head to http://ndoc.sourceforge.net Although it hasn ’ t been upgraded for some time, it ’ s still functional (as long as you use the NET

Trang 29

Framework 1.x version) It is possible that the project may become live again at some point in the future,

so it ’ s worth a look Figure 31 - 11 shows an example of NDoc documentation in a help - style format

Figure 31-11

With the possible demise of NDoc, it is worth looking at Sandcastle, an alternative tool It ’ s the tool that

Microsoft uses to generate API documentation, so it is as fully featured as you would expect it to be It

has full support for the latest NET Framework version and C# language features, including support for

example generics that NDoc does not support

However, as Sandcastle is effectively an internal tool, it is not the easiest thing to use Several GUIs exist

for the tool, most of which have been created by its users

You can find out more at www.sandcastledocs.com or http://blogs.msdn.com/sandcastle You

can also download a popular GUI for Sandcastle at www.codeplex.com/SHFB

Trang 30

Summar y

In this chapter, you looked at all aspects of XML documentation, from how to create it to what you can

do with it Specifically, you have learned the following:

XML documentation syntax How to include external XML documentation How XML documentation is used in VS IntelliSense and the Object Browser How to use class diagrams to add XML documentation

How to generate XML documentation files How to process XML documentation files in C# How to style XML documentation with XSLT How to use tools such as NDoc and Sandcastle to compile help files from XML documentation Admittedly, adding XML documentation to your projects can be a time - consuming process, and it can make your source code look a bit messy; but in large - scale projects, it is an essential part of development, and the result is well worth the effort — especially when you use a tool designed for the purpose

2 Which top - level XML documentation tags would you use to document a property?

3 XML documentation is contained in C# source files True or false?

4 What is the major disadvantage of adding XML documentation using a class diagram?

5 What do you need to do to ensure that other projects can make use of XML documentation in your class libraries?

Trang 32

32

Networ king

Chapter 21 dealt with a high - level technology to communicate across the network: Web Services

You learned how to send messages from the client to the server in a platform - independent way with the SOAP and NET - specific protocols In this chapter, you step into lower networking layers, programming with classes from the namespace System.Net Web Services itself uses this

TcpListener and TcpClient Socket programming

Networ king Over view

Networking is about communicating with applications on other systems The communication happens by sending messages Messages can be sent to a single system where a connection is initiated before the message, as shown in Figure 32 - 1 , or messages can be sent to multiple systems

by a broadcast , as shown in Figure 32 - 2 With a broadcast, connections are not initiated; the

messages are just sent to the network instead

Trang 33

Sender

Connection

Figure 32-1

Networking can be best illustrated by showing the seven OSI layers Figure 32 - 3 shows the stack of the

OSI layers with their corresponding TCP/IP layers Often the layers are also defined by numbers that are

simply increments of the layers — from the bottom, where the physical layer is number 1, to the top,

where the application layer is number 7

ReceiverReceiver

Receiver

Receiver

Sender

Figure 32-2

Trang 34

TCP UDP

PresentationSessionTranspor tNetworkData Link

Internet Protocol

EthernetPhysical

Figure 32-3

The lowest OSI layer is the physical layer At the physical layer, physical devices (such as networking cards and cables) are defined The data link layer accesses the physical network with physical addresses The data link layer performs error correction, flow control, and hardware addressing The address of your Ethernet network card shows up when you use the ipconfig /all command The system shown here has the MAC address 00 - 13 - 02 - 38 - 0D - 5C:

C:\ > ipconfig /all Windows IP Configuration

Host Name : farabove Primary Dns Suffix : explorer.local Node Type : Hybrid

IP Routing Enabled : No WINS Proxy Enabled : No DNS Suffix Search List : explorer.local kabsi.at

Wireless LAN adapter Wireless Network Connection:

Connection-specific DNS Suffix : kabsi.at Description : Intel(R) PRO/Wireless 3945ABG Network Connection

Physical address : 00-13-02-38-0D-5C DHCP Enabled : Yes

Autoconfiguration Enabled : Yes Link-local IPv6 Address : fe80:bd:3d27:4106:9f4c%10(Preferred) IPv4 Address : 192.168.0.31(Preferred)

Subnet Mask : 255.255.255.0 Lease Obtained : Sunday, July 29, 2007, 3:10:08 PM Lease Expires : Wednesday, August 01, 2007, 3:10:08 PM Default Gateway : 192.168.0.6

DHCP Server : 192.168.0.6 DHCPv6 IAID : 167777026 DNS Servers : 192.168.0.10 195.202.128.2 NetBIOS over Tcpip : Enabled

Trang 35

The network layer uses a logical address to address systems in a WAN The Internet Protocol (IP) is a

layer 3 protocol; at layer 3, an IP address is used to address other systems In IPv4, the IP address

consists of 4 bytes — for example, 192.14.5.12

The transport layer is used to identify the applications that communicate The applications can be

identified by endpoints The server application waiting for clients to connect has a known endpoint to

connect to Both the Transmission Control Protocol (TCP) and User Datagram Protocol (UDP) are layer 4

protocols that use a port number (the endpoint) to identify an application The TCP protocol is used for

reliable communication in which a connection is set up before data is sent; whereas with the UDP

protocol, communication is unreliable because data is sent without a guarantee that it will be received

Above layer 4, the OSI layers define a session, presentation, and application layer The session layer

defines services for an application, such as logging in to and out of an application The session

layer enables a virtual connection between applications You can compare this with ASP.NET sessions,

discussed in Chapter 18 The presentation layer is about data formatting — it is within this layer that

encryption, decryption, and compression can happen Finally, the application layer is the highest layer to

offer networking features to applications, such as file transfers, e - mail, Web browsing, and so on

With the TCP/IP protocol suite, the application - level protocols cover layers 4 to 7 of the OSI layer model

A few examples of these protocols are Hypertext Transfer Protocol (HTTP), File Transfer Protocol (FTP),

and Simple Mail Transfer Protocol (SMTP) At the transport layer, endpoints are used to reach other

applications; these application protocols define how the data that is sent to the other system looks Later

you will see what data is sent with HTTP

Name Resolution

The Internet Protocol requires IP addresses Because the IP addresses aren ’ t easy to remember (and are

even more difficult with IPv6, where the IP address consists of 128 bits instead of 32 bits), a hostname is

used For communication between the systems, however, the IP address is required, as discussed earlier

To map the hostname to the IP address, Domain Name System (DNS) servers are used

Windows has a command - line tool, nslookup, that can do name lookups (resolve IP addresses from

hostnames) or reverse lookups (resolve hostnames from IP addresses) Reverse lookups are interesting

because by analyzing the log files where the IP address of client systems can be found, you can

determine the origin of the client system

With NET, you can perform name lookups with the Dns class in the System.Net namespace With the

Dns class, a hostname can be resolved to its IP addresses, or an IP address can be resolved to its

hostname Let ’ s try it out with a simple project

Try It Out Using DNS

1 Create a new C# console application project named DnsLookup in the directory

C:\BegVCSharp\Chapter32

2 Import the namespace System.Net

Trang 36

3 Invoke the GetHostEntry() method of the Dns class, as shown here, after checking the arguments from the Main() method:

static void Main(string[] args) {

if (args.Length != 1) {

Console.WriteLine(“Usage: DnsLookup hostname/IP Adddress”);

return;

} IPHostEntry ipHostEntry = Dns.GetHostEntry(args[0]);

4 Add the following code to the Main() method that follows the call to the

GetHostEntry() method to write information about the resolved host to the console:

Console.WriteLine(“Host: {0}”, ipHostEntry.HostName);

if (ipHostEntry.Aliases.Length > 0) {

foreach (IPAddress address in ipHostEntry.AddressList) {

Console.WriteLine(“Address: {0}”, address.ToString());

} }

5 Compile the application and start the program Pass a hostname as a command - line argument —

for example, www.microsoft.com To start it from Visual Studio, you can set the command - line arguments with the Debug configuration, as shown in Figure 32 - 4 You can also start a command prompt, change to the directory of the executable, and start the application with

dnslookup www.microsoft.com You should get output that looks similar to the following:

Host: lb1.www.ms.akadns.net

Address(es):

Address: 207.46.193.254Address: 207.46.19.190Address: 207.46.19.254Address: 207.46.192.254

Trang 37

How It Works

The Dns class queries the DNS server to resolve hostnames to IP addresses and to do reverse lookups

to get a hostname from an IP address To do this, the Dns class uses the GetHostEntry() method, with

which you can pass a hostname, and an IPHostEntry will be returned For reverse lookups, the

GetHostByAddress() method can be called

In all cases, the Dns class returns an IPHostEntry This class wraps information about a host The

IPHostEntry class has three properties: HostName returns the name of the host, Aliases returns a list

of all alias names, and AddressList returns an array of IPAddress elements The ToString() method of

the IPAddress class returns the Internet address in a standard notation

Uniform Resource Identifier

The resources that can be accessed across the network are described by a URI (Uniform Resource

Identifier) You use URIs every day when you enter Web addresses, such as http://www

.thinktecture.com , in your Web browser The class Uri encapsulates a URI and has properties and

methods for parsing, comparing, and combining URIs

A Uri object can be created by passing a URI string to the constructor:

Uri uri = new Uri(“http://www.wrox.com/go/p2p”);

If you go to different pages on the same site, you can use a base URI and construct out of it URIs that

contain the directories:

Uri baseUri = new Uri(“http://msdn.microsoft.com”);

Uri uri = new Uri(baseUri, “downloads”);

Figure 32-4

Trang 38

You can access parts of the URI by using properties of the Uri class The following table shows a few examples of what you can get out of an Uri object that is initialized with the URI http://www.wrox.com/marketbasket.cgi?isbn=0470124725

Uri Property Result

Scheme http

Host www.wrox.com

Port 80

LocalPath /marketbasket.cgi

The UDP protocol is similar in that the server must create a socket with a well - known port number, and the client uses a freely available port number The difference is that the client doesn ’ t initiate a connection Instead, the client can send the data without making a connection first Without a connection, there ’ s no guarantee that the data is received at all, but the overall transfer is faster The UDP protocol has the big advantage that broadcasts can be done with it — sending information to all systems in the LAN by using a broadcast address

Broadcast addresses are IP addresses for which all bits of the host part of the IP address are set to 1

Application Protocols

This section looks at application protocols that make use of TCP or UDP HTTP is an application protocol that is layered on top of TCP The HTTP protocol defines the message that is sent across the network

Trang 39

Using the HTTP protocol to request data from a Web server, a TCP connection is opened, and then an

HTTP request is sent An example of an HTTP request initiated by a browser looks like this:

Accept-Encoding: gzip, deflate

User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; NET CLR

2.0.50727; Media Center PC 5.0; Tablet PC 2.0; NET CLR 1.1.4322; NET CLR

3.5.20706; NET CLR 3.0.590)

Host: localhost:80

Connection: Keep-Alive

This sample request shows a GET command Some of the most frequently used HTTP commands are

GET , POST and HEAD GET is used to request a file from the server With the POST command, a file is

requested from the server, too, but unlike with the GET command, with the POST command additional

data is sent after the HTTP header With the HEAD command, the server returns only the file ’ s

header information, so that the client can determine whether the file is different from data already in

the cache

The GET command requests the file on the server Here, the server should return the file /default

.aspx The last section of the first line defines the HTTP version If both the client and server support

version 1.1, then this version is used for the communication Otherwise, HTTP 1.0 is used With HTTP

1.1 it is possible to keep the same connection (see the HTTP header information Connection:

Keep - Alive )

After the first line of the request with the GET command, HTTP header information follows The browser

sends information about itself with the request In the example, you can see the Accept information,

where mime types of supported programs are sent The Accept - Language header defines the languages

that are configured on the browser The server can use this information to return different information to

the client, depending on the supported files and languages With the User - Agent header, the browser

sends information about the client application used to request the page from the server Here, Internet

Explorer 7.0 is used with Windows Vista Windows Vista has the identifier Windows NT 6.0 The server

can also read whether the NET runtime is installed on the client system Here, NET 1.1, NET 2.0, NET

3.0, and NET 3.5 appear as supported NET versions

After the server receives a GET request, a response message is returned An example of a response

message is shown in the following example If the request succeeds, then the first line of the response

shows an OK status and the HTTP version used Then HTTP header information follows, which includes

the Server , the Date , and the Content - Type and the length that follows the header The header and the

content are separated by two lines:

HTTP/1.1 200 OK

Server: Microsoft-IIS/7.0

Date: Sun, 29 Jul 2007 20:14:59 GMT

X-Powered-By: ASP.NET

Trang 40

X-AspNet-Version: 2.0.50727Cache-Control: privateContent-Type: text/html; charset=utf-8Content-Length: 991

< !DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.0 Transitional//EN” >

< HTML >

HEAD >

< title > Demo < /title >

You can easily simulate an HTTP request by using the telnet utility, which you do with the next Try It Out

Try It Out Simulate an HTTP Request

1 Start the telnet client by typing telnet.exe at a command prompt The prompt Microsoft Telnet > appears With Windows Vista, the telnet client is not installed by default If it is missing on your system, then select Control Panel Programs Turn Windows Features On

or Off; and select the check box for the Telnet Client to install it

2 To see the commands you type and send to the server, enter set localecho in the telnet session

3 Create a connection to the Web server in your LAN If you have a Web server on the local

system, enter open localhost 80 80 is the default port number used with the Web server

4 Send a request to the Web server by typing the command GET / HTTP/1.1 , and then press

Return twice With the / , the default page from the server is returned — for example,

default.htm Instead of using the / , you can request specific filenames Sending two newline characters marks the end of the transmission Now you get a response from the server that looks similar to the response shown earlier

Networ king Programming Options

The System.Net and System.Net.Sockets namespaces offer several options for networking programming Figure 32 - 5 shows those options The easiest way to do network programming is by using the WebClient class Just a single method of this class is needed to get files from a Web server or to transfer files to an FTP server However, the functionality of this class is limited With NET 3.5, you can use it only with the HTTP and the FTP protocols, and to access files Of course, you can also plug in custom classes to support other protocols

Ngày đăng: 09/08/2014, 14:21

TỪ KHÓA LIÊN QUAN