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

Professional ASP.NET 1.0 Special Edition- P32 pps

40 194 0
Tài liệu đã được kiểm tra trùng lặp

Đ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 đề Transactions in .net
Trường học Wrox Press
Chuyên ngành Computer Science
Thể loại Essay
Năm xuất bản 2001
Thành phố Birmingham
Định dạng
Số trang 40
Dung lượng 790,97 KB

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

Nội dung

The manifest contains the meta data required to specify: ƒ The assembly version ƒ The security information for the assembly ƒ The scope of the assembly ƒ Information to resolve refer

Trang 1

instead of the original component When we execute the modified page, displayProducts_ovr.aspx, we can see that the

new value for average price is now displayed We will also add some code to display the newest product:

Transactions in NET

To provide integration with COM+, the CLR provides the same declarative transaction model This allows managed objects

to participate in existing transactions We can use these transactions from within ASP.NET pages, and also from within NET components

At the ASP.NET page level you can add a page-level directive for this:

<%@ Page Transaction="Required" %>

The allowable values are:

Disabled Transactional context will be ignored This is the default

NotSupported The page does not run within a transaction The object context is created without a transaction

Supported The page runs within the scope of an existing transaction, if one is active If no transaction scope is

active, the page runs without a transaction

Required The page runs within the scope of a transaction, either an existing one, or creating one if no existing

transaction exists

RequiresNew The page requires a new transaction, and one will be created for each page request

To participate in the transaction success or failure, you can either rely on transaction AutoComplete or explicitly commit

or abort the transaction With AutoComplete enabled, your page will vote to commit the transaction if the page runs without throwing an exception AutoComplete is enabled by default on a page, so if the page completes successfully, then the page will vote to commit

You can also explicitly control the transaction result by calling the methods of the ContextUtil class To vote to abort

Trang 2

a transaction, you call:

A serviced component has its configuration information held by the COM+ catalog When you use a serviced component within your application, COM+ will create a context service layer based on the attributes you have assigned to your serviced component Basically, the context service layer runs within COM+ Services, and communicates with your serviced components, which are still running within NET

There are several steps to go through to create serviced components:

ƒ Derive your class from the System.EnterpriseServices.ServicedComponent class

ƒ Add the TransactionAttribute to your class

ƒ Create a strong name for the assembly

ƒ Add assembly attributes to identify the strong name, and the COM+ application name

ƒ Register the assembly with the COM+ catalog This can be manually done, or under certain circumstances, done automatically (this is called lazy registration)

Creating a Serviced Component Class

Creating the class and adding the attributes is simple Here is an example written in Visual Basic NET:

Option Explicit

Trang 3

Public Sub Transfer(FromAC As String, ToAC As String, Amt As Decimal)

Dim f As String = "Transferring " & Amt.ToString() & " from " _

& FromAC & " to " & ToAC

Trang 4

<assembly:ApplicationName("DotNetBank")>

The AssemblyKeyFile attribute is used to indicate the file that contains the public and private keys for the strong name for this assembly Later in this chapter, we will look at strong-named assemblies These types of assemblies are required

if we want to have multiple versions of an assembly executable at the same time on the same system The

ApplicationName attribute defines the COM+ application that this NET component will execute within If the application is not found, then COM+ will create an application with the name supplied- in this case DotNetBank

<Transaction(TransactionOption.RequiresNew)>

The other attribute that has been included with this component is the Transaction attribute This attribute specifies the transaction parameter for this component In this case, we want to make sure that the component executes inside a new transaction The parameter that we pass is an enum defined as TransactionOption.RequiresNew

The C# version of the serviced component is nearly identical to the Visual Basic NET version The only difference is the syntax that is used to denote the attributes within the code Whereas in the Visual Basic NET version, we used < > to delineate the attributes, the C# version uses [ ] to indicate the attributes:

Trang 5

string f = "Transferring " + Amt.ToString() + " from " +

Additional Assembly Attributes

As well as the ApplicationName attribute, you can also add COM+ component details, such as:

ƒ ApplicationActivation, to determine how the assembly is activated (Library or Server)

ƒ ApplicationID, to specify a GUID

ƒ Description, to give the assembly a description

For example, in Visual Basic NET these would be:

<assembly:ApplicationActivation(ActivationOption.Library)>

<assembly:ApplicationID("guid")>

<assembly:Description(".NET bank assembly")>

Accessing COM+ Context

To access the COM+ context from the NET serviced component, you use the

System.EnterpriseServices.ContextUtil class There are no major performance penalties since the cost to transition into COM+ context is very small The context (including transactions) flows with the call, so transactions automatically flow

Trang 6

Registering the Serviced Component

Classes using COM+ services must be registered, which can be done using the Register Services Tool The syntax is:

regsvcs [Options] AssemblyName

where Options can be one of:

/fc Find or create a target application This is a default

/c Create the target application, generating an error if it already exists

/exapp Expect an existing application

/tlb:tlbfile Filename for the exported type library

/appname:name Use the specified name for the application

/parname:name Use the specified name or ID for the target partition

/extlb Use an existing type library

/reconfig Reconfigure the existing target application This is a default

/noreconfig Do not reconfigure the existing target application

/u Uninstall the target application

/componly Configure only the components, not methods or interfaces

/nologo Suppress logo output

/quiet Suppress logo and success output

Using this utility performs the following actions:

ƒ Loads the assembly

ƒ Registers the assembly

ƒ Generates a type library

ƒ Registers the type library

ƒ Installs the type library into the COM+ application

ƒ Configures the COM+ application

For example, to register the bank assemblies:

Trang 7

If you then examine the COM+ Component Services, you'll see the NET components

These can be treated like any other transactional COM+ component

Lazy Registration

If a serviced component is used from managed code, and it is not already registered as part of a COM+ application, then the registration and configuration is performed automatically for you This may seem like an ideal solution, but it does require administrative privileges, so is not suitable for all scenarios By and large, it is best to manually register components, perhaps as part of the installation

Trang 8

Serviced Component Security

Integration with COM+ security is also provided as part of serviced components, allowing access to the

SecurityContext object of the COM+ application For this to succeed the managed code needs to obtain an NT security token and perform impersonation before calling the NET object

What are Assemblies?

There is no concept of an assembly as a file- there is no such thing as a assembly file that we have to worry about now

The assembly is a collection of files that together make up the assembly The only requirement is that these files need to all reside in the same directory on the disk When they are placed into an assembly, the CLR treats all these as a single unit

As you can see from the above figure, the manifest is what is used to describe the contents of the application The manifest can either be embedded within a single DLL, as seen in the single file assembly, or can be in a separate file, as

is the case with the multi-file assembly When we talk about DLLs in NET, they are just a bit different from what they were

in COM or Win32 While the extension is the same, they are executed by the CLR, instead of being executed as native code

Trang 9

The assembly can be thought of as a logical DLL In the past, we would distribute components or resources through the deployment of a DLL Now, we can distribute the pieces of an assembly in the same way The main difference is that the DLL needed some other information somewhere- usually in the registry- to tell the system that it was there ready to run With an assembly, it carries that information along with it, in its meta data

An assembly is not an application An application is built from one or more assemblies The assemblies that make up an application can be deployed in a number of different ways Since an assembly contains its own meta data, it is capable of telling the operating system all about itself It does not rely on entries into the registry to describe itself

This association of meta data with executable code simplifies the distribution of an application All you need to do to deploy an application is simply to copy all of the assemblies that make up the application to a directory on the disk This

is known as XCOPY deployment, since the only tool required to deploy the files to disk is the XCOPY console command When the application is first executed, the meta data within the assemblies tells the system all that it needs to know in order to execute the application As we saw earlier, this may not always be the case If you are using serviced components, these need to be registered with COM+

You can also use more traditional installation mechanisms to distribute applications built out of assemblies You can build

an .msi file and use the Windows Installer to deploy the files into the correct location Likewise, you can build a CAB file

and have a browser download the file to the system and then execute the application In either case, all that the installation mechanism is responsible for is getting the proper files into the proper location on the destination system- no information about the assemblies needs to be added to the registry of the target system

Assemblies and Versioning

There are currently two problems with the Win32 architecture that have combined to give us what is known as DLL Hell

In DLL Hell, there is no control entity that is responsible for all of the DLL files installed onto a system Information about

a COM DLL is held in the registry It can be easily overwritten by another application For DLLs that aren't COM DLLs, there

is no entry whatsoever in the registry An application install program can also overwrite an existing DLL This can play havoc with any existing application that was relying on that particular DLL performing a specific function when a method

is called

One of the specific problems with Win32 is that there is no system-level enforcement of versioning rules between components It is left up to 'best practices' coding, which says that once an interface is published it can never be changed, but there is nothing in the operating system that explicitly prevents this The other problem is that there is no common way for an application to say that it needs version 1.2.1.1234 of a particular component It is left up to the developer to check the version of a DLL before calling into it If that check is not done, and the application finds a different version, then the code that it is relying on may no longer be there, or it may not perform the function that it expects, even if the interface is still intact To attempt to combat this, Windows 2000 added System File Protection This is an OS feature that can stop any installation program from overwriting any system DLLs

The CLR extends this support by allowing developers to specify the specific version of a component that they want their application to use It provides all of the support to make sure that the proper version is located and used for the requesting

Trang 10

application In doing this, it also allows for the execution of code from two similar components, only differing in version This is known as side-by-side execution and we will look at that a bit later in the chapter

Assembly Manifest

In order for an assembly to describe itself to the CLR, it must contain a set of meta data This meta data is contained in the assembly's manifest The manifest contains the meta data required to specify:

ƒ The assembly version

ƒ The security information for the assembly

ƒ The scope of the assembly

ƒ Information to resolve references to the resources and classes of the assembly

The manifest for an assembly can either be stored in an EXE or DLL file, or in a standalone file Remember that the assembly can be made up of one or more files- in which case there isn't a specific file that contains the entire assembly

In a single file assembly, the manifest is part of the DLL or EXE file that is the assembly

The manifest of an assembly lists all of the files and resources that make up the assembly It also lists all of the classes and types defined in the assembly, and specifies which resources or files within the assembly map to which classes or types The manifest also identifies any other assemblies on which it is dependent

In creating a multi-file assembly, the Assembly Generation tool (AL.EXE) is used to create the manifest for the assembly

To create a multi-file assembly, you compile the individual source files without an assembly Then the AL tool is used to read through the compiled modules and create an assembly for the full set of modules

Meta data

The manifest will specifically contain these pieces of meta data:

ƒ Assembly Name - This is a textual string name that identifies the assembly When an assembly is used by one application, the developer can generally enforce a unique name for each assembly, thus preventing name collisions However, when an assembly is designed to be shared, a more unique naming method must be used This is called a strong name, and creating one allows the assembly to be stored in the global assembly cache The global assembly cache is used to store assemblies that can be used by several applications on a machine

To store an assembly into the global assembly cache, there are three steps that have to be followed:

First, you must create a strong name for the assembly using the SN.EXE tool This tool will generate a file that contains the necessary public and private keys to define a strong name

Second, the contents of that file are passed to the Assembly Generation Tool (AL.EXE) to create an assembly with a

Trang 11

strong name associated with it

Finally, to install the assembly into the global assembly cache, you will use the Global Assembly Cache Tool

(GACUTIL.EXE) This is a tool that is used to manipulate the contents of the global assembly cache, including adding components to the GAC

ƒ Version Information - The components of the version number are the major and minor version numbers, a build number, and a revision number This is represented as a set of four numbers with the format:

<major version>.<minor version>.<build number>.<revision>

When the CLR is checking to see if an assembly is the proper version, it first checks the major and minor version numbers These must match in order for the assembly to be compatible If these two numbers match but the build number is different, then as long as the build number of the assembly is greater than the build required by the application, it can be assumed to be backwards-compatible with the version expected by the application

ƒ Assembly File List - Lists each file contained in the assembly, along with the relative path to the file For version

1 of the NET Framework, all files in an assembly must be in the same directory as the manifest file This only holds true for a multi-file assembly

ƒ Type reference information - Maps all of the types included in the assembly to the specific file in the assembly that contains the type This is necessary so that any types referenced within the classes contained in the assembly can be resolved by the runtime

ƒ Referenced assemblies - Lists all of the other assemblies that are statically referenced within the types contained

in this assembly Each entry contains the name of the assembly along with the required version information

There is also custom meta data that can be included by the developer Only the developer can use this information - the CLR does not use this information in any way In the first release of the NET architecture, there are two sets of custom assembly meta data The first set is made up of nine classes from the System.Reflection namespace You can use this namespace to query the values for this meta data at run-time System.Reflection meta data includes:

ƒ Company information

ƒ Build information, such as 'Retail' or 'Debug'

ƒ Copyright information

ƒ Additional naming and version information

ƒ Assembly Title and Description

ƒ Product and Trademark Information

The second set is made up of classes from the System.Runtime.CompilerServices namespace This meta data includes:

Trang 12

ƒ Cultures or spoken languages supported by the assembly, not programming languages.

ƒ Operating systems and processors the assembly has been built to support Version 1 of the CLR does not use this information

Since the components within an assembly are so thoroughly defined by the meta data, you can even define a new class that inherits from an existing class directly from the compiled code - you don't need to access the sourcecode to do this

In fact, the components do not even need to be in the same language, as long as both are managed components We saw

an example of this earlier

The assemblies and the components within them are said to be self-describing This means that they carry all the information that other components need to know in order to interact with them This information is all carried within the meta data of the assembly There are no more IDL files in the NET architecture or public header files that get out of sync with the executables, and you can always be sure that the meta data information being used by the runtime is the proper meta data for the code being executed, since they are held together in the assembly

Side-by-Side Execution

The ability to run multiple versions of the same component at the same time is a very valuable feature of the CLR It can even execute two versions of the same component within the same process The ability to do this is called side-by-side execution By allowing this, the NET architecture offers the developer an advantage over architectures such as COM While there have been ways in the past to do side-by-side execution, the implementation of it in NET frees the developer from most of the worries associated with doing it By handling it in the plumbing of the CLR, the developer only has to worry about the business-specific code in their application

When creating new versions of a component, a developer doesn't have to worry as much about maintaining compatibility with previous versions Since the older component can run right alongside the new component, and the application using the component knows which version of the component to use, both can co-exist peacefully on the same machine There are some precautions that the developer must take into account when having components that will run side-by-side with previous versions For example, if the component is relying on a physical file as a data cache, then two components executing side-by-side will try to access the same file The components would need to be written such that they keep the file in a location that is dependent on the version of the component being executed

Trang 13

Summary

The flexibility and power of the NET architecture extends beyond just creating applications, web services, and ASP.NET pages We can create powerful business components using the NET Framework and the CLR that have just as much power and flexibility as COM objects In some cases, the capabilities offered by the CLR provide distinct advantages over COM Now we can actually derive new objects from classes written in different languages And we can do this even if all

we have is the compiled version of the base class However, that doesn't mean that we can't have COM and NET work together in the same application

In this chapter, we have specifically looked at:

ƒ How to write a business object in two different languages, and then use the same test program to work with both objects

ƒ How to take a class written in one language and extend its functionality by deriving a new class in a totally different language

ƒ How to make use of transactions in your ASP.NET pages and within your NET components

ƒ How assemblies and meta data provide a way to package the executable code along with detailed descriptions of the code that is executing

Trang 14

Building ASP.NET Server Controls

Since the early days, COM developers around the world have been building reusable visual controls In the early 90's, building such controls required significant time and investment in understanding the myriad of COM interfaces that a control had to implement and use

Later in the decade, C/C++ frameworks like the Microsoft Foundation Classes (MFC) and the Active Template Library (ATL) made control development a little easier They provided reusable classes and templates that implemented a lot of plumbing code required for controls But the true breakthrough in popular control development didn't really happen until

1996 when the release of the Visual Basic Control Creation edition made control creation far simpler, and consequently very popular globally

The upside of control development, and the reason why people still write so many controls today, is reusability Once you have conquered visual control development, the reward of being able to write a control once (the grid control being the canonical example) and then reuse it in numerous control containers (such as Word, Excel, etc.) makes it worth all the pain You can, of course, reuse the control in your own suite of products, not to mention the fact that you could make a good living selling them to other developers These same advantages apply in the world of ASP.NET controls, but there is one big difference: ASP.NET controls are easy to get started with

ASP.NET allows you to build reusable visual controls that can render themselves as HTML or any other mark-up language such as WML Many high level similarities can be drawn between COM controls and ASP.NET controls, as they both enable reuse within UIs But in reality, they are very different in the way they are implemented ASP.NET provides a clean and easy-to-use class hierarchy for implementing controls, and there are no esoteric interfaces or threading models that are difficult to understand ASP.NET still uses interfaces, but there really aren't more than a couple you'll use on a regular basis

In this chapter we're going to look at ASP.NET control development covering:

ƒ When, why, and how you can build ASP.NET controls in both Visual Basic NET and C#

ƒ How controls form the basis of all page rendering in ASP.NET

ƒ How controls persist state across page invocation

ƒ How controls interact with postback and can raise events

Trang 15

ƒ Building controls that, themselves, use other controls to render their UI

Writing a Simple Control

To demonstrate the basic principles of control development and to show how easy ASP.NET control development is, we'll kick off this chapter by writing a simple Label control, which can render a text message We'll initially develop the control

in C#, review the code, and then rewrite it using VB This example will hopefully prove to you that control development really isn't that difficult, and it is, at the very least, worth understanding how controls are written so you can better understand how ASP.NET renders pages

Trang 16

it is good practice to include it

ƒ System.Web.UI - contains the ASP.NET control classes, many of which are divided up into namespaces based upon their family (System.Web.UI.WebControls, System.Web.UI.HtmlControls, etc.) This reference

is needed as we are using the Control and HtmlTextWriter classes

The next line of the code marks the beginning scope of a new namespace we have chosen for our control called

WroxControls:

namespace WroxControls

{

Anything declared within the next section of the code until the end of the namespace seven lines later is a member of the

WroxControls namespace This means that the full namespace-qualified reference to our control is

WroxControls.MyFirstControl Any code using our class must use this full name unless the Using directive is included to import all definitions within our namespace into its default scope

The next few lines of code declare the class for our server control:

public class MyFirstControl : Control

{

protected override void Render(HtmlTextWriter writer)

Trang 17

{

writer.Write("<h1>ASP.NET Control Development in C#</h1>");

}

}

The class is called MyFirstControl It's derived from the class Control, (which is part of the System.Web.UI

namespace) declared as public, and has one protected method called Render The Control class implements the basic plumbing code required by a server control to be used within an ASP.NET page

The name of the class is arbitrary and you can call your controls whatever you like, as they are defined in your own namespace You should avoid using names that are already used by ASP.NET (or any other part of the runtime), as name conflicts will occur if two namespaces are imported using the @Import directive by a page, or the using directive inside

of a source file If you decided to create your own label control do not call it Label; call it YourLabel or some other meaningful name such as WroxLabel

By marking our class as public, we are stating that anybody can create an instance of our class and use it If we specify that it is private (by omitting the public attribute), the class will only be usable by other classes within the same namespace If an ASP.NET page attempts to access a private class, the runtime will raise an error saying the class/type

is not defined This is somewhat confusing when trying to track down an error, so it is always worth checking the access control of a class as it is easy to forget to add the public keyword when developing

The Render method is declared using the override keyword This keyword tells the compiler that the base class

Control implements the Render member, but our class wants to override the method so that it can control the output created at run-time itself The implementation of this method calls the Write method of the HtmlTextWriter object, which results in the HTML "<h1>ASP.NET Control Development in C#</h1>" being written to the page output stream

Once you have created a server control and compiled it (as we'll demonstrate shortly), you can use it in an ASP.NET page

To do this, you use the @Register page directive to associate a tag prefix with a namespace containing a server control, and then use the tag prefix plus the class name of a server control, as shown here:

<%@ Register TagPrefix="Wrox" Namespace="WroxControls" Assembly="MyFirstControl" %>

<html>

<body>

Trang 18

<Wrox:MyFirstControl runat="server" />

</body>

</html>

Create a new file called myfirstcontrol.aspx to contain this ASP.NET page

This page tells the ASP.NET page compiler that when it sees any element starting with 'Wrox:' it should search the namespace WroxControls for a class whose name matches the element name (that is, MyFirstControl)

Furthermore, the assembly attribute defines the physical assembly in which the class is contained At run-time, assuming ASP.NET located the class, it creates an instance of it, and calls its Render method to allow it to write data to the output stream being created (for example, the page)

The position of the HTML that a control creates in the final page depends upon where that control is declared inside the ASP.NET page code In this page we'd expect the server controls output to be rendered after the body tag

In this example, once our control has inserted its HTML into the output stream, the final page sent down to the client browser will look like this:

Trang 19

To test the ASP.NET page yourself and view the output, you need to compile the C# sourcecode to create an assembly This is placed in the bin directory of the application on your web server, causing the ASP.NET runtime to scan the assembly and make an internal note of the namespaces and classes/controls within it

Compiling the C# Control and Creating an Assembly

To compile our server control class, bring up your text editor, enter the following batch commands, and save the file as

make.bat:

set outdir= \bin\MyFirstControl.dll

set assemblies=System.dll,System.Web.dll

csc /t:library /out:%outdir% /r:%assemblies% MyFirstControl.cs

For the class to compile correctly, you'll need to change the outdir parameter ' ', in line one, to match a directory on your machine that is configured as a virtual directory

The first two lines of the make.bat file declare a couple of variables These make the line that actually does the compilation more readable The compiler options are discussed in Chapter 3 The important points to note about this file are:

ƒ A reference to the System.dll and System.Web.dll assemblies is added using the /r parameter We have

to do this so that the compiler knows where to search for the namespaces/classes we're importing into our control with the using directive If you do not add a reference to the assembly containing referenced classes you'll get a compile error

ƒ The output of the compiler (MyFirstControl.dll) is placed directly into our web application's bin directory When ASP.NET has to create a class at runtime, this directory is searched Using the meta data contained in our assembly, ASP.NET will know where to locate the WroxControls namespace specified in the page's

Trang 20

@Register directive By compiling our control directory to the bin directory, we are less likely to forget to copy the assembly

Run the make.bat file, and you'll see some output like this:

If all goes well, check that the bin directory contains the compiled assembly If it exists, you should be able to open the ASP.NET page we created earlier and see the output of the control

First Control Complete

Although the C# control we've just developed is about as simple as it gets, and doesn't really have any practical use as yet, you've just seen the full development cycle required for a simple ASP.NET control Hopefully, you now realize that: (a) control development is nothing like it was in the COM days, and (b) maybe control development is worth checking out

in more detail Things will get more advanced from here on in, but all of the code is clean and fairly easy to understand once you've grasped the basic concepts that we've been discussing

To show that control development in Visual Basic is just as painless, we'll create an almost identical control called

MyFirstControlInVB

Control Development in Visual Basic

One of the great things about Visual Basic NET is that the language has arrived in the 21st Century with a bang It now has all the object-oriented (OO) features that make it a first-class programming language However, as you'd expect, the

VB team and C# teams at Microsoft are competing with each other for adopters, and as a result they have used different names for certain attributes and directives within their respective languages that they feel are more suitable for their audience of programmers This is fair enough, but it does means that switching between the languages can be a little confusing at first

Ngày đăng: 03/07/2014, 07:20