> Eighth write component in C # (Rainbow translation) (from heavy particle space)

Source: Internet
Author: User
Tags bool error code exception handling html page connect variable tostring try catch
The eighth chapter writes the component with C #

This chapter is about writing components in C #. You learned how to write a component, how to compile it, and how to use it in a client program. A further step is to use namespaces to organize your applications.
This chapter is composed of two main large:
。 Your first component.
。 Work with the name space

8.1 Your first component
The examples mentioned so far in this book are the use of a class directly in the same application. The class and its users are included in the same execution file. Now we'll detach the class and the consumer from the component and the customer, each in a different binary (executable).
Although you still create a DLL for your component, the steps differ greatly from writing a COM component in C + +. You rarely relate to the bottom tier structure. The following subsections describe how to build a component and the customers that use it:

。 Building components
。 Compiling components
。 Create a simple customer application

8.1.1 Building Components
Because I am a fan of using examples, I decided to create a web-related class for your convenience. It returns a Web page and is stored in a string variable for later reuse. All of these are written for reference. The help documentation for the NET Framework.
The class name is requestwebpage; it has two constructors--a property and a method. Property is named a URL, and it stores the web address of the Web page, which is returned by the method GetContent. This method does all the work for you (see Listing 8.1).

Listing 8.1 Requestwebpage class for returning an HTML page from a Web server

1:using System;
2:using System.Net;
3:using System.IO;
4:using System.Text;
5:
6:public class Requestwebpage
7: {
8:private const int buffer_size = 128;
9:private string m_strURL;
10:
11:public Requestwebpage ()
12: {
13:}
14:
15:public requestwebpage (String strurl)
16: {
17:m_strurl = strURL;
18:}
19:
20:public string URL
21: {
22:get {return m_strurl;}
23:set {m_strurl = value;}
24:}
25:public void GetContent (out string strcontent)
26: {
27://Check URL
28:if (m_strURL = "")
29:throw New ArgumentException ("URL must be provided.");
30:
31:webrequest therequest = (WebRequest) webrequestfactory.create (m_strURL);
32:webresponse theresponse = Therequest.getresponse ();
33:
34://Set byte buffer for response
35:int bytesread = 0;
36:byte[] Buffer = new Byte[buffer_size];
37:
38:stream responsestream = Theresponse.getresponsestream ();
39:bytesread = Responsestream.read (Buffer, 0, buffer_size);
40:
41://Use StringBuilder to speed up the allocation process
42:stringbuilder strresponse = new StringBuilder ("");
43:while (bytesread!= 0)
44: {
45:strresponse.append (Encoding.ASCII.GetString (Buffer,0,bytesread));
46:bytesread = Responsestream.read (Buffer, 0, buffer_size);
47:}
48:
49://Assign to output parameters
50:strcontent = Strresponse.tostring ();
51:}
52:}

This should have been done with the parameterless constructor, but I decided to initialize the URL in the constructor, which might be useful. When a later decision is made to change the URL-to return to the second page, for example, the get and set access flags of the URL property make it public.
The interesting thing begins with the GetContent method. First, the code is very simple to check the URL, if it does not fit, it will throw a ArgumentException exception. After that, I asked Webrequestfactory to create a WebRequest object based on the URL passed to it.
Because I don't want to send cookies, attach headers, and query strings, I immediately visit WebResponse (line 32nd). If you need to request any of these features, you must implement them before this line.
Lines 35th and 36 initialize a byte buffer that is used to read data from the return stream. Temporarily ignoring the StringBuilder class, the while loop simply repeats as long as there is still data to be read in the return stream. The last read operation returns zero, thus ending the loop.
Now I want to go back to the StringBuilder class. Why use an instance of this class instead of simply merging a byte buffer into a string variable? Look at the following example:
strmystring = strmystring + "some more text";
It is clear here that you are copying the value. The constant "some more text" is framed with a string variable type, and a new string variable is created based on the addition operation. It was then assigned to Strmystring. There's a lot of copies, right?
But you could be arguing.
Strmystring + + "some more text";
Don't show off this behavior. Sorry, this is a wrong answer for C #. The operation is exactly the same as the assignment operation described.
Another way of not addressing the problem is to use the StringBuilder class. It works with a buffer, and then you do the append, insert, delete, and replace operations without the copy behavior I described. That's why I use it in a class to merge the content that is read from the buffer.
The buffer takes me into the last important code fragment in this class-the encoding conversion of line 45th. It just involves me getting the requested character set.
Finally, when all the content is read and converted, I explicitly request a string object from StringBuilder and assign it to the output variable. A return value will still result in another copy operation.

8.1.2 Compilation Component
So far, the work you've done is no different from writing a class within a normal application. The difference is the compilation process. You must create a library instead of an application:
Csc/r:system.net.dll/t:library/out:wrq.dll Webrequest.cs
compiler switch/t:library tells C # to compile, to create a library instead of searching for a static Main method. Again, because I am using the System.Net namespace, I must refer to its library, which is System.Net.dll.
Your library is named Wrq.dll and now it is ready for a client application. Because in this chapter I only work with private components, so you don't have to copy the library to a particular location, but copy it to the client application directory.

8.1.3 Create a simple client application
When a component is written and successfully compiled, all you have to do is use it in the client application. I created a simple command-line application again, and it returned to the first page of a development site I maintained (see Listing 8.2).

Listing 8.2 Returns a simple Web page with the Requestwebpage class

1:using System;
2:
3:class Testwebreq
4: {
5:public static void Main ()
6: {
7:requestwebpage WRQ = new Requestwebpage ();
8:wrq. URL = "http://www.alphasierrapapa.com/iisdev/";
9:
10:string strresult;
11:try
12: {
13:wrq. GetContent (out strresult);
14:}
15:catch (Exception e)
16: {
17:console.writeline (e);
18:return;
19:}
20:
21:console.writeline (strresult);
22:}
Members

Notice that I have included a call to GetContent in a try catch statement. One reason for this is that getcontent may throw a ArgumentException exception. In addition, I call inside the component. NET Framework classes can also throw exceptions. Because I can't handle these exceptions inside the class, I have to deal with them here.
The rest of the code is simply a simple component use-invoking a standard constructor, accessing a property, and executing a method. But wait a minute: you need to be aware of when to compile the application. Be sure to tell the compiler to let it refer to your new Component library DLL:
Csc/r:wrq.dll Wrclient.cs
Now that everything is ready, you can test the program. The output will scroll, but you can see the application work. Using a regular expression, you can also add code to parse the returned HTML and extract the information based on your personal preferences. I envision using this new version of SSL (Secure Sockets Layer) for online credit card verification in asp+ Web pages.
You may notice that there is no special using statement for the library you created. The reason is that you do not define a namespace in the source file of the component.

8.2 Use the name space work
You often use name spaces, such as system and system.net. C # uses namespaces to organize programs, and layered organizations make it easier for members of a program to spread to another program.
Although not mandatory, you always create namespaces to clearly identify the hierarchy of your application. NET Framework gives good ideas for building this layering.
The following code fragment shows the declaration of a simple namespace my.test (dot denotes a hierarchical level) in the original file of C #:

Namespace My.test
{
Anything here belongs to the name space.
}

When you access a member of a namespace, it is also necessary to use the namespace identifier to fully validate it, or to use the using flag to bring all members into your current namespace. The previous examples in this book show how to apply these techniques.
There are only a few words about access security before you begin to use the name space. If you do not add a specific access modifier, all types will be default to internal. Use public when you want to access the type from outside. No other modifiers are allowed.
This is a theory about the full name space. Let's go ahead and implement the theory--The following sections explain how to use namespaces when building component applications
。 Wrapping classes in namespaces
。 Using Namespaces in client applications
。 Add more classes to the namespace

8.2.1 Packing class in namespaces
Now that you know the theoretical meaning of the namespace, let's realize it in real life. In this and upcoming examples, the name space of natural selection is presenting.csharp. To keep you from getting bored, just wrapping requestwebpage into Presenting.csharp, I decided to write a class for Whois lookup (see listing 8.3).

Listing 8.3 implements the Whoislookup class in the namespace

1:using System;
2:using System.Net.Sockets;
3:using System.IO;
4:using System.Text;
5:
6:namespace Presenting.csharp
7: {
8:public class Whoislookup
9: {
10:public static bool Query (string strdomain, out string strwhoisinfo)
11: {
12:const int buffer_size = 128;
13:
14:if ("" = = Strdomain)
15:throw New ArgumentException ("You must specify a domain name.");
16:
17:tcpclient TCPC = new TcpClient ();
18:strwhoisinfo = "N/a";
19:
20://Attempt to connect WHOIS server
21:if (TCPC. Connect ("whois.networksolutions.com", 43)!= 0)
22:return false;
23:
24://Get Stream
25:stream s = tcpc. GetStream ();
26:
27://Send Request
28:strdomain + = "\ r \ n";
29:byte[] Bdomarr = Encoding.ASCII.GetBytes (Strdomain.tochararray ());
30:s.write (Bdomarr, 0, strdomain.length);
31:
32:byte[] Buffer = new Byte[buffer_size];
33:stringbuilder strwhoisresponse = new StringBuilder ("");
34:
35:int bytesread = s.read (Buffer, 0, buffer_size);
36:while (bytesread!= 0)
37: {
38:strwhoisresponse.append (Encoding.ASCII.GetString (Buffer,0,bytesread));
39:bytesread = S.read (Buffer, 0, buffer_size);
40:}
41:
42:tcpc. Close ();
43:strwhoisinfo = Strwhoisresponse.tostring ();
44:return true;
45:}
46:}
47:}

The namespace is declared on line 6th, and it encloses the Whoislookup class in the large brackets in lines 7th and 47th. To declare your new name space, that's what you actually have to do.
There are certainly some interesting code in the Whoislookup class, especially since it illustrates how easy it is to use C # for socket programming. After not-so-stellar domain name checking in static Query method, I instantiated an object of type TcpClient, which is used to complete all traffic on the 43 port of the WHOIS server. A server connection was established on line 21st:
if (TCPC. Connect ("whois.networksolutions.com", 43)!= 0)
This method cannot throw an exception because the connection failure is the expected result. (Do you Remember "want" and "don't" for exception handling?) The return value is an error code, and a return of zero indicates a successful connection.
For Whois lookups, I must first send some information to the server-the domain name I am looking for. To do this, you first get a bidirectional stream (line 25th) that references the current TCP connection. Then attach the last carriage return/newline pair to the domain name to indicate the end of the inquiry. Re-pack the byte array and send a request to the WHOIS server (line 30th).
The rest of the code is very similar to the Requestwebpage class. In this class, I use a buffer again to read the response from the remote server. When the buffer completes the read, the connection is disconnected. The returned response was forwarded to the caller. The reason I explicitly called the Close method is that I don't want to wait for the garbage collector to destroy the connection. The connection time should not be too long to occupy the scarce resource of the TCP port.
Before you can use a class in a. NET component, you must compile it as a library. Although there is now a defined namespace, the compilation command remains unchanged:
Csc/r:system.net.dll/t:library/out:whois.dll Whois.cs
Note that if you want the library to be named the same way as the C # source file, there is no need to specify the/out: switch. It is a good practice to stipulate that the switch is not only composed of a single source file. If you specify multiple source files, the library is named after the first name in the list.

8.2.2 use of namespaces in client applications
Because you use the namespace development component, the client also introduces the namespace
Using Presenting.csharp;
Or use the full qualifying name (fully qualified name) for the members in the namespace, for example
Presenting.CSharp.WhoisLookup.Query (...);

If you do not expect conflicts between the members introduced in the namespace, the using flag (Directive) is preferred, especially since you have very few types. A sample of the client program that uses the component is given in Listing 8.4.

Listing 8.4 Testing the Whoislookup component

1:using System;
2:using Presenting.csharp;
3:
4:class Testwhois
5: {
6:public static void Main ()
7: {
8:string strresult;
9:bool Breturnvalue;
10:
11:try
12: {
13:breturnvalue = Whoislookup.query ("microsoft.com", out strresult);
14:}
15:catch (Exception e)
16: {
17:console.writeline (e);
18:return;
19:}
20:if (Breturnvalue)
21:console.writeline (strresult);
22:else
23:console.writeline ("Could not obtain information from server.");
24:}
25:}

Line 2nd introduces the Presenting.csharp namespace using the using flag. Now, whenever I refer to whoislookup, I can ignore the full qualifying name of the namespace.
The program makes a whois lookup of the microsoft.com domain-you can also replace microsoft.com with your own domain name. Allowing command-line arguments to pass a domain name can give customers a wider range of uses. Listing 8.5 implements this functionality, but it does not implement proper exception handling (in order to make the program shorter).

Listing 8.5 passing command line arguments to query method

1:using System;
2:using Presenting.csharp;
3:
4:class Whoisshort
5: {
6:public static void Main (string[] args)
7: {
8:string strresult;
9:bool Breturnvalue;
10:
11:breturnvalue = Whoislookup.query (Args[0], out strresult);
12:
13:if (Breturnvalue)
14:console.writeline (strresult);
15:else
16:console.writeline ("Lookup failed.");
17:}
18:}

All you have to do is compile the application:
Csc/r:whois.dll Whoisclnt.cs
You can then use command-line arguments to execute the application. For example, execute with the microsoft.com parameter
WHOISCLNT microsoft.com
When the query runs successfully, Microsoft.com registration information appears. (Listing 8.6 shows the abbreviated version of the output) this is a handy little program, written in a modular way, and takes less than one hours. How long will it take if you write in C + +? Luckily, I can no longer remember how long it took to do this for the first time in C + +.

Listing 8.6 about Microsoft.com (abbreviated) WHOIS information
D:\csharp\samples\namespace>whoisclient
...

Registrant:
Microsoft Corporation (Microsoft-dom)
1 Microsoft Way
Redmond, WA 98052
US
Domain Name:MICROSOFT.COM

Administrative Contact:
Microsoft hostmaster (mh37-org) Msnhst@MICROSOFT.COM
Technical Contacts, Zone contact:
MSN NOC (mn5-org) Msnnoc@MICROSOFT.COM
Billing Contact:
Microsoft-internic billing Issues (mdb-org) Msnbill@MICROSOFT.COM

The record is last updated on 20-may-2000.
Record expires on 03-may-2010.
Record created on 02-may-1991.
Database last updated on 9-jun-2000 13:50:52 EDT.

Domain servers in listed order:

Atbd. Microsoft.com 131.107.1.7
DNS1. Microsoft.com 131.107.1.240
DNS4. Cp. Msft.net 207.46.138.11
DNS5. Cp. Msft.net 207.46.138.12

8.2.3 add multiple classes to namespaces
How wonderful it is to make the whoislookup and Requestwebpage classes coexist in the same name space. Since Whoislookup is already part of the namespace, you only have to make the Requestwebpage class part of that namespace.
The necessary changes are easy to apply. All you need to do is use the namespaces to encapsulate the Requestwebpage class:

Namespace Presenting.csharp
{
public class Requestwebpage
{
...
}
}

Although two classes are contained in two different files, they are part of the same namespace after compilation:
Csc/r:system.net.dll/t:library/out:presenting.csharp.dll Whois.cs Webrequest.cs

You don't have to name the DLL according to the namespace name. However, doing so will help you more easily remember which library to reference when compiling a client application.

8.3 Summary
In this chapter, you learned how to build a component that can be used in a client program. Initially, you don't have to care about namespaces, but this feature is described in the second component later. namespaces, both externally, are a good way to organize your applications.
Components in C # are easy to build, and you don't even have to make special installations as long as libraries and applications coexist in the same directory. The steps change when you want to create a class library that must be used by more than one customer-and the next chapter will tell you why.



Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.