.NET REMOTING
Introduction
Unless you have spent the last two years in hibernation, you must already be aware of XML Web Services and its powers. Despite all the attention Web Services have received as an ultimate solution to distributed computing, let us face the ground reality. There are still thousands of applications running on intranets and there would be thousands more that would be developed in future.
The goal of these applications is not to carry out cross–platform communication across heterogeneous systems (which is the strength of Web Services). In such cases there is no point in building these applications as Web Services as they may not be able to provide the desired performance and capabilities. Instead using .NET Remoting to carry out client–server communication would be an excellent solution.
Application Boundaries
An application boundary defines the scope of an application. It encompasses various resources critical to an application's execution, such as address space, executable code and the data used by the application. A typical multiprogramming execution environment, such as Windows, uses application boundaries to protect one application from affecting the execution of another application.
In this section, you'll learn about the application boundaries supplied by Windows and the .NET Framework. You'll understand how application boundaries protect applications from poorly designed or faulty code. You'll also learn how application boundaries make it difficult to design applications that want to communicate beyond application boundaries.
Process Boundary
A process is an application under execution. Windows isolates processes from each other to ensure that code running in one process cannot adversely affect other processes. Windows achieves this isolation by creating a process boundary. A process boundary ensures that
Each process has its own virtual address space, executable code, and data.
A Windows process cannot directly access the code or data of another Windows process.
A Windows process runs only one application, so if an application crashes, it does not affect other applications.
Process boundaries are a good thing because they allow processes to coexist. However, it takes lot of system resources to create, monitor, and terminate a process. In addition, when the processor switches between the processes, the processor must save and reset the execution context of the processes. Often an application would involve several short-lived processes, which require the system to spend a lot of resources just for process management.
Application Domain Boundary
The Common Language Runtime (CLR) provides a managed execution environment for the .NET applications. The managed execution environment provides various services to the executing code; including cross-language integration, code access security, object lifetime management, and debugging and profiling support. This is why code executed by the CLR is also known as managed code.
Unlike Windows, the CLR can verify the type-safety of programs to guarantee that a program does not request resources outside of its own boundary. The characteristics of the CLR help provide isolation between running programs at a lower cost than the process boundary.
Instead of a process, the basic unit of isolation for running applications in the CLR is an application domain. An application domain (also known as an AppDomain) is the smallest execution unit for a .NET application. The CLR allows several application domains to run within a single Windows process and still provides the same level of isolation between applications as provided by a Windows process.
The application domains achieve isolation through application domain boundaries, which ensure that
Each application domain contains its own set of code, data, and configuration settings.
An application domain cannot directly access the code or data structures of another application domain.
Code running in one application domain cannot affect other application domains. The CLR can terminate an application domain without stopping the entire process.
Creating, monitoring, and maintaining an application domain uses fewer resources than performing the same operations with a process. In addition, the capability of an application domain to run multiple applications within the same process reduces the overhead of process switching. Thus, application domains increase the performance of the applications.
You can create an application domain in a program using the AppDomain class of System namespace. However, in most cases the application domains are created and managed by the runtime hosts that execute your code. Runtime hosts provide the environment to run managed code on behalf of the user. When you install the .NET Framework, you get three runtime hosts already configured—the Windows shell, ASP.NET, and Internet Explorer.
Distributed Applications
From the previous sections, you can see that both process and application domains provide a closely protected environment. As a result, objects in a process or an application domain cannot directly talk to objects in another process or application domain.
However, in the increasingly connected world, enterprises and users demand distributed applications. Distributed applications allow objects to talk across process boundaries. Often, distributed applications also meet the following objectives:
Establishes communication between objects that run in different application domains and processes whether on the same computer or across the Internet.
Enables enterprise application integration by establishing communication between objects that run on heterogeneous architectures.
Enables application availability by making sure that portions of an application continue to run even if some components are busy or have failed.
Provides increased security and scalability by dividing the application into several layers (or tiers).
Evolution of Distributed Applications
A well-designed distributed application has the potential to be more connected, more available, more scalable, and more robust than an application in which all components run on a single computer. This is a desirable model for an enterprise application.
Several efforts have been made to design frameworks for developing distributed applications. A few well-known frameworks are Distributed Computing Environment/Remote Procedure Calls (DEC/RPC), Microsoft Distributed Component Object Model (DCOM), Common Object Request Broker Architecture (CORBA), and Java Remote Method Invocation (RMI). Some of these implementations are widely deployed in enterprises.
However, modern business requirements are different from earlier days. Today, businesses seek solutions that can be developed rapidly, that integrate well with their legacy applications, and that interoperate well with their business partners. Each of the previously mentioned technologies failed to satisfy one or more of these requirements.
In 2000, Microsoft introduced the .NET Framework for designing next-generation, distributed applications. As you'll explore more in this book, the .NET Framework is specifically targeted to meet the needs of modern business whether the need is rapid development, integration, or interoperability.
Developing Distributed Applications Using the .NET Framework
The .NET Framework provides various mechanisms to support distributed application development. Most of this functionality is present in the following three namespaces of the Framework Class Library (FCL):
The System.Net Namespace—This namespace includes classes to create standalone listeners and custom protocol handlers to start from scratch, as well as to create your own framework for developing a distributed application. Working with the System.Net namespace directly requires a good understanding of network programming.
The System.Runtime.Remoting Namespace—This namespace includes the classes that constitutes the .NET remoting framework. The .NET remoting framework enables communication between objects living in different application domains whether or not they are on the same computer. Remoting provides an abstraction over the complexities of network programming and exposes a simple mechanism for interapplication domain communication. The key objectives of .NET remoting are flexibility and extensibility.
The System.Web.Services Namespace—This namespace includes the classes that constitute the ASP.NET Web services framework. ASP.NET Web services enable objects living in different application domains to exchange messages using standard protocols such as HTTP and SOAP. ASP.NET Web services, when compared to remoting, provide a much higher level of abstraction and simplicity. The key objectives of ASP.NET Web services are ease of use and interoperability with other systems.
Both .NET remoting and ASP.NET Web services provide a complete framework for designing distributed applications. Most programmers will use either .NET remoting or ASP.NET Web services instead of building a distributed programming framework from scratch using the System.Net namespace classes.
The functionality offered by .NET Remoting and ASP.NET Web services appears very similar to each other. In fact, ASP.NET Web services are actually built on the .NET Remoting infrastructure. It is also possible to design Web services using .NET remoting. Given the amount of similarity, how do you choose one over another in your project? Simply put, the decision depends on the type of application you want to create. You'll use
.NET Remoting when both of the endpoints (client and server) of a distributed application are in your control. This might be a case when an application has been designed for use within a corporate network.
ASP.NET Web services when one of the endpoints of a distributed application is not in your control. This might be a case when your application is interoperating with your business partner's application.
.NET Remoting Architecture
.NET remoting enables objects in different application domains to talk to each other. The real strength of remoting is in enabling communication between objects when their application domains are separated across the network. In this case, remoting transparently handles details related to network communication.
Before getting into details, let's first answer a basic question—How can remoting establish cross-application domain communication when an application domain does not allow direct calls across its boundary?
Remoting takes an indirect approach to application domain communication by creating proxy objects . Both application domains communicate with each other using the following steps:
When a client object wants to create an instance of the server object, the remoting system at the client side instead creates a proxy of the server object. The proxy object lives at the client but behaves just like the remote object; this leaves the client with the impression that the server object is in the client's process.
In a simplified view of .NET remoting, note that the client and server communicate indirectly through a proxy object.
When the client object calls a method on the server object, the proxy passes the call information to the remoting system on the client. This remoting system in turn sends the call over the channel to the remoting system on the server.
The remoting system on the server receives the call information and, on the basis of it, invokes the method on the actual object on the server (creating the object if necessary).
The remoting system on the server collects all the results of the method invocation and passes them through the channel to the remoting system on the client.
The remoting system at the client receives the response of the server and returns the results to the client object through the proxy.
The process of packaging and sending method calls among the objects across the application boundaries via serialization and deserialization, as shown in the preceding steps, is also known as marshalling.
Now that you have a basic idea of how .NET remoting works, its time to get into details. In the next few sections, I'll explain the various key components and terminology of .NET remoting.
Object Marshalling
Remotable objects are objects that can be marshalled across the application domains. In contrast, all other objects are known as non-remotable objects. There are two types of remotable objects:
Marshal-by-value (MBV) Objects—These objects are copied and passed out of the server application domain to the client application domain.
Marshal-by-reference (MBR) Objects—These objects are accessed on the client side using a proxy. The client just holds a reference to these objects.
Marshal-by-Value Objects
MBV objects reside on the server. However, when the client invokes a method on the MBV object, the MBV object is serialized, transferred over the network, and restored on the client as an exact copy of the server-side object. The method is then invoked directly on the client. When this happens, the MBV object is no longer a remote object. Any method calls to the object do not require any proxy object or marshalling because the object is locally available.
The MBV objects can provide faster performance by reducing the number of network roundtrips, but in the case of large objects, the time taken to transfer the serialized object from the server to the client can be very significant. Further, MBV objects do not allow you the flexibility to run the remote object in the server environment.
A MBV object can be created by declaring a class with the Serializable attribute; for example
' Define a MBV remoting object
Public Class MyMBVObject
' Implementation details
End ClassIf a class needs to control its own serialization, it can do so by implementing the ISerializable interface as shown here:
Imports System.Runtime.Serialization
' Define a MBV remoting object
Public Class MyMBVObject
Implements ISerializable
' Class details ...
'Implement custom serialization here
Public Sub GetObjectData( _
ByVal info As SerializationInfo, _
ByVal context As StreamingContext)
' Serialization details ...
End Sub
End ClassMarshal-by-Reference Objects
MBR objects are remote objects. They always reside on the server, and all methods invoked on these objects are executed at the server side. The client communicates with the MBR object on the server using a local proxy object that holds the reference to the MBR object.
Although the use of MBR objects increases the number of network roundtrips, they are a good choice when the objects are prohibitively large or when the functionality of the object is only available in the server environment on which it is created.
An MBR object can be created by deriving from the System.MarshalByRefObject class; for example,
' Define a MBR remoting object
Public Class MyMBRObject
Inherits MarshalByRefObject
' Class details ...
End ClassChannels
Create and consume a .NET Remoting object: Select a channel protocol and a formatter. Channel protocols include TCP and HTTP. Formatters include SOAP and binary.
Channels are the objects that transport messages across remoting boundaries such as application domains, processes, and computers. When a client calls a method on a remote object, the details of the method call are transported to the remote object through a channel. Any results returned from the remote object are communicated back to the client again through the same channel.
The .NET remoting framework ensures that before a remote object can be called, it has registered at least one channel with the remoting system on the server. Similarly, the client object should specify a channel before it can communicate with a remote object. If the remote object offers more than one channel, the client can connect using the channel that best suits its requirements.
A channel has two endpoints. The channel object at the receiving end of a channel (the server) listens to a particular protocol using the specified port number, whereas the channel object at the sending end of the channel (the client) sends information to the receiving end using the protocol and port number specified by the channel object on the receiving end.
Formatters
Formatters are the objects used to encode and serialize data into messages before they are transmitted over a channel.
To participate in the .NET remoting framework, a formatter class must implement the IFormatter interface. The .NET Framework packages two formatter classes for common scenarios—the BinaryFormatter class and the SoapFormatter class. If you want to use a different formatter, you can define your own formatter class by implementing the IFormatter interface.
The SOAP Formatter
SOAP (Simple Object Access Protocol) is a relatively straightforward, XML-based protocol for exchanging types and messages between applications. SOAP is an extensible and modular protocol; it is not bound to a particular transport mechanism such as HTTP or TCP.
The SOAP formatter is implemented in the SoapFormatter class of the System.Runtime.Serialization.Formatters.Soap namespace.
SOAP formatting is an ideal way of communicating between applications that use incompatible architectures. However, SOAP is very verbose. SOAP messages require more bytes to represent data than the equivalent binary messages.
The Binary Formatter
Unlike SOAP, the binary format used by the .NET Framework is proprietary and can be understood only within .NET applications. However, as compared to SOAP, the binary format of representing messages is very compact and efficient.
The binary formatter is implemented in the BinaryFormatter class of the System.Runtime.Serialization.Formatters.Binary namespace.
Channels and Formatters
The HTTP channel uses the SOAP formatter as its default formatter to transport messages to and from the remote objects. The HTTP channel uses SoapClientFormatterSinkProvider and SoapServerFormatterSinkProvider classes to serialize and deserialize messages using SoapFormatter. You can create industry-standard XML Web services by using the SOAP formatter with the HTTP channel.
The TCP channel uses the binary format by default to transport messages to and from the remote object. The TCP channel uses BinaryClientFormatterSinkProvider and BinaryServerFormatterSinkProvider classes to serialize and deserialize messages using BinaryFormatter.
However, channels are configurable. You can configure the HTTP channel to use the binary formatter or a custom formatter instead of the SOAP formatter. Similarly, the TCP channel can be configured to use the SOAP formatter or a custom formatter instead of the binary formatter.
Figure 3.2 compares the various combinations of channels and formatters on the scale of efficiency and compatibility. The protocols at the top of the list are the most efficient, while those at the bottom of the list are most interoperable. You can use this information to decide which combination of channel and formatter you would choose in a given scenario.
Remote Object Activation
Between the two types of objects that you have seen (MBV objects and MBR objects), only MBR objects can be activated remotely. No remote activation is needed in the case of MBV objects because the MBV object itself is transferred to the client side.
TIP
Remotable Members An MBR object can remote the following types of members:
Non-static public methods
Non-static public properties
Non-static public fields
Based on the activation mode, an MBR object is classified into one of the following two categories:
Server-activated objects
Client-activated objects
Server-Activated Objects
Server-activated objects (SAO) are those remote objects whose lifetime is directly controlled by the server.
When a client requests an instance of a server-activated object, a proxy to the remote object is created in the client's application domain. The remote object is only instantiated (or activated) on the server when the client calls a method on the proxy object.
Server-activated objects provide limited flexibility because they can only be instantiated using their default (parameter-less) constructors.
NOTE
Well-Known Objects Remote objects activated in SingleCall or Singleton activation mode are also known as well-known objects.
There are two possible activation modes for a server-activated object:
SingleCall activation mode
Singleton activation mode
SingleCall Activation Mode
In the SingleCall activation mode, an object is instantiated for the sole purpose of responding to just one client request. After the request is fulfilled, the .NET remoting framework deletes the object and reclaims its memory.
Objects activated in the SingleCall mode are also known as stateless because the objects are created and destroyed with each client request; therefore, they do not maintain state across requests. This behavior of SingleCall mode allows for greater server scalability as an object consumes server resources only for a small period, therefore allowing the server to allocate resources to other objects.
The SingleCall activation mode is a desired solution when
The overhead of creating an object is not significant.
The object is not required to maintain its state.
The server needs to support a large number of requests for the object.
The object needs to be supported in a load-balanced environment.
TIP
Load-Balancing and SingleCall Activation Sometimes to improve the overall efficiency of an application, it might be hosted on multiple servers that share the incoming requests to the application. In this case, a request can go to any of the available servers for processing. This scenario is called a load-balancing environment.
Because the SingleCall objects are stateless, it does not matter which server processes requests for such objects. For this reason, SingleCall activation is ideally suited for load-balanced environments.
Common scenarios of the SingleCall activation mode are those applications in which the object is required by the client to do a small amount of work and then the object is no longer required. Some common examples are retrieving the inventory level for an item, displaying tracking information for a shipment, and so on.
Singleton Activation Mode
In the Singleton activation mode, at most there will be one instance of the remote object regardless of the number of clients accessing it.
A Singleton-mode object can maintain state information across method calls. For this reason, such objects are also sometimes known as stateful objects. The state maintained by the Singleton-mode object is globally shared by all of its clients. This generally means that you should not store any state in Singleton-mode objects. But there are circumstances (such as keeping track of usage statistics) in which it can make sense to store shared state.
A Singleton object does not exist on the server forever. Its lifetime is determined by the lifetime lease of the object. I'll discuss lifetime leases later in the chapter.
A Singleton object is a desired solution when
The overhead of creating an object is substantial.
The object is required to maintain its state over a prolonged period.
Several clients need to work on the shared state.
Singleton activation mode is useful in scenarios such as in a chat server in which multiple clients talk to the same remote object and share data between one another through this object.
Client-Activated Objects
Client-activated objects (CAO) are those remote objects whose lifetime is directly controlled by the client. This is in direct contrast with SAOs, where the server, not the client, has the complete control over the lifetime of the objects.
Client-activated objects are instantiated on the server as soon as the client requests the object to be created. Unlike an SAO, a CAO does not delay the object creation until the first method is called on the object.
A CAO can be created using any of the available constructors for the class. A typical CAO activation involves the following steps:
When the client attempts to create an instance of the server object, an activation request message is sent to the remote server.
The server then creates an instance of the requested class using the specified constructor and returns an ObjRef object to the client application that invoked it. The ObjRef object contains all the required information to generate a proxy object that is capable of communicating with a remote object.
The client uses the ObjRef object to create a proxy for the server object on the client side.
An instance of a CAO serves only the client responsible for its creation, and the CAO doesn't get discarded with each request. For this reason, a CAO can maintain state with each client that it is serving, but unlike the Singleton SAO, different CAOs cannot share a common state.
The lifetime of a CAO is determined using lifetime leases. I'll talk more about this topic shortly in a section titled "Lifetime Leases."
A CAO is a desired solution when
The clients want to maintain a private session with the remote object.
The clients want to have more control over how the objects are created and how long they will live.
A CAO is useful in scenarios such as entering a complex purchase order in which multiple roundtrips are involved and clients want to maintain their own private state with the remote object.
Comparing the Object Activation Techniques
Based on the discussions in the previous section, the various object activation techniques can be compared as shown in Figure 3.3.
The SingleCall server activation has maximum scalability because such objects occupy server resources for the minimum amount of the time. This enables the server to allocate its resources between a large numbers of clients.
On the other hand, the client activation of remote objects offers maximum flexibility because you have complete control over the construction and lifetime of the remote object.
Applying .NET Remoting
Applying .NET Remoting
So far, I have discussed the architecture and various concepts related to the .NET remoting. In this section, you will learn how to apply these concepts to see remoting in action. In particular, you will learn how to
Create a remotable class.
Create a Server-activated object.
Create a Client-activated object.
Use configuration files to configure the remoting framework.
Use interface assemblies to compile remoting clients.
Creating a Remotable Class
Creating a remotable class is simple. All you need to do is to inherit a class from the MarshalByRefObject class. Step By Step 3.1 creates a remotable class named DbConnect. This class connects to a specified SQL Server database and allows you to execute a SELECT SQL statement using its ExecuteQuery() method.
STEP BY STEP 3.1: Creating a Remotable Class
Launch Visual Studio .NET. Select File, New, Blank Solution, and name the new solution 310C03. Click OK.
Add a new Visual Basic .NET Class library named StepByStep3-1 to the solution.
In the Solution Explorer, rename the default Class1.vb to DbConnect.vb.
Open the DbConnect.vb class and replace the code with the following code:
Imports System
Imports System.Data
Imports System.Data.SqlClient
' Marshal-by-Reference Remotable Object
Public Class DbConnect
Inherits MarshalByRefObject
Private sqlconn As SqlConnection
' Default constructor connects to the Northwind
' database
Public Sub New()
sqlconn = New SqlConnection( _
"data source=(local);" & _
"initial catalog=Northwind;" & _
"integrated security=SSPI")
Console.WriteLine( _
"Created a new connection " & _
"to the Northwind database")
End Sub
' Parameterized constructor connects to the
' specified database
Public Sub New(ByVal DbName As String)
sqlconn = New SqlConnection( _
"data source=(local);" & _
"initial catalog=" & DbName & ";" & _
"integrated security=SSPI")
Console.WriteLine( _
"Created a new connection " & _
"to the " & DbName & " database")
End Sub
Public Function ExecuteQuery( _
ByVal strQuery As String) As DataSet
Console.Write("Starting to execute " & _
"the query...")
' Create a SqlCommand to represent the query
Dim sqlcmd As SqlCommand = _
sqlconn.CreateCommand()
sqlcmd.CommandType = CommandType.Text
sqlcmd.CommandText = strQuery
' Create a SqlDataAdapter object
' to talk to the database
Dim sqlda As SqlDataAdapter = _
New SqlDataAdapter()
sqlda.SelectCommand = sqlcmd
' Create a DataSet to hold the results
Dim ds As DataSet = New DataSet()
Try
' Fill the DataSet
sqlda.Fill(ds, "Results")
Catch ex As Exception
Console.WriteLine(ex.Message, _
"Error executing query")
End Try
Console.WriteLine("Done.")
ExecuteQuery = ds
End Function
End ClassSelect Build, Build StepByStep3-1. This step packages the remotable class into the file StepByStep3-1.dll, which is located in the bin or directory of your project. You can navigate to it through the Solution Explorer: Just select the project and click the Show All Files button in the Solution Explorer toolbar.
You've now created a remotable class, but it cannot yet be directly called from client application domains. For a remotable class to be activated, you need to connect the class to the remoting framework. You'll learn how to do that in the next section.
Creating a Server-Activated Object
A remotable class is usually connected with the remoting framework through a separate server program. The server program listens to the client request on a specified channel and instantiates the remote object or invokes calls on it as required.
It is a good idea to keep the remotable class and server program separate; this enables the design to be modular and the code to be reusable.
In this section, I'll show you how to create a remoting server. Here's an overview of the steps that the remoting server must take.
Create a server channel that listens on a particular port to the incoming object activation requests from other application domains. The following code segment shows how to create a TCP server channel and an HTTP server channel:
' Register a TCP server channel on port
Dim channel As TcpServerChannel = _
New TcpServerChannel(1234)
' Register a HTTP server channel on port
Dim channel As HttpServerChannel = _
New HttpServerChannel(1234)Register the channel with the remoting framework. This tells the framework which requests should be directed to this particular server. This registration is performed through the RegisterChannel() method of the ChannelServices class:
' Register the channel with remoting framework
ChannelServices.RegisterChannel(channel)Register the remotable class with the remoting framework. This tells the framework which classes this particular server can create for remote clients. For a server-activated object, this registration is performed using the RegisterWellKnownServiceType() method of the RemotingConfiguration class, as shown here:
' Register a remote object with the remoting framework
RemotingConfiguration.RegisterWellKnownServiceType( _
GetType(DbConnect), "DbConnect", _
WellKnownObjectMode.SingleCall)Here, the first parameter is the type of the remotable class. The second parameter specifies the uniform resource identifier (URI) through which the server publishes the location of the remote object. The last parameter specifies the activation mode. The activation mode can be one of the two possible values of the WellKnownObjectMode enumeration—SingleCall or Singleton.
TIP
Accessing an Object Through Multiple Channels From steps 2 and 3, you can note that the channel registration and the remote object registration are not related. In fact, a remote object can be accessed through all registered channels.
With the channel and class both registered, the remoting server is ready to go. The remoting framework will direct all requests for that class via that channel to the registered server.
As I discussed, earlier, an SAO can be activated in two different modes—SingleCall and Singleton. In the next few sections, I'll cover how to create a remoting server for activating objects in each of these modes. I'll also tell the story on the other side of the channel; that is, how to connect the client program to the remoting framework so that it can instantiate the SAO and call methods on it.
Registering a Remotable Class As a Server-Activated Object Using the SingleCall Activation Mode
In this section, I'll demonstrate how to create a server that exposes the remotable class through the remoting framework. The server process here will be a long running user interface-less process that will continue to listen for incoming client requests on a channel.
Ideally, you should write this type of server program as a Windows service or use an existing Windows service such as Internet Information Services (IIS) to work as a remoting server. But I have chosen to write the server program as a console application mainly because I'll use the console Window to display various messages that will help you understand the workings of the remoting server.
Later in this chapter, in the section "Using IIS As an Activation Agent," I'll cover how to use IIS as a remoting server. I'll talk about Windows services in Chapter 6, "Windows Services."
STEP BY STEP 3.2: Registering a Server-Activated Object Using the SingleCall Activation Mode
Add a new Visual Basic .NET Console application named StepByStep3-2 to the solution.
In the Solution Explorer, right-click the project StepByStep3-2 and select Add Reference from the context menu. In the Add Reference dialog box (see Figure 3.4), select the .NET tab, select the System.Runtime.Remoting component from the list view, and click the Select button. Now select the Projects tab, select the Project named StepByStep3-1 (which contains the remotable object) from the list view, and click the Select button. Both the selected projects then appear in the Selected Components list, as shown in Figure 3.4. Click OK.
In the Solution Explorer, rename the default Module1.vb module to DbConnectSingleCallServer.vb. Open the file and change the name of the module to DbConnectSingleCallServer in the module declaration.
NOTE
Namespace Naming Note that although the project is named StepByStep3-1, the corresponding namespace is named StepByStep3_1. That's because the .NET Framework considers a dash to be an illegal character in a namespace name.
Add the following Imports directives above the module declaration:
Imports StepByStep3_1
Imports System.Runtime.Remoting
Imports System.Runtime.Remoting.Channels
Imports System.Runtime.Remoting.Channels.TcpAdd the following code in the Main() procedure:
Public Sub Main()
' Create and Register a TCP server channel
' that listens on port
Dim channel As TcpServerChannel = _
New TcpServerChannel(1234)
ChannelServices.RegisterChannel(channel)
' Register the service that publishes
' DbConnect for remote access in SingleCall mode
RemotingConfiguration. _
RegisterWellKnownServiceType( _
GetType(StepByStep3_1.DbConnect), "DbConnect", _
WellKnownObjectMode.SingleCall)
Console.WriteLine("Started server in the " & _
"SingleCall mode")
Console.WriteLine("Press to terminate " & _
"server...")
Console.ReadLine()
End SubRight-click on the StepByStep3-2 project in the Solution Explorer and select Properties. Change the Startup object to DbConnectSingleCallServer.
Build the project. This step creates a remoting server that is capable of registering the StepByStep3_1.DbConnect class for remote invocation using the SingleCall activation mode.
Step by Step 3.2 uses a receiver TCP channel (TcpServerChannel) to register a remotable class with the remoting framework. However, converting this program to use HTTP channel is not difficult—you just need to change all instances of Tcp to Http.
Step By Step 3.2 creates a remoting host that listens on port 1234. This is an arbitrary port number that might or might not work on your computer. A good idea is to check whether a port is already in use by some other application before running this program. You can do this from the command line on a particular computer by using the Windows netstat command.
This suggestion works only in a test scenario. It is not reasonable to instruct a customer to check whether the port is available before he starts the application. If the application will run entirely on your company's network, you can safely use a port in the private port range of 49152 through 65535—provided, of course, that the port number you choose is not used by any other internal application. In case you are distributing the application, you should get a port number registered with the IANA (Internet Assigned Numbers Authority). You can see a list of already assigned port numbers at http://www.iana.org/assignments/port-numbers.
Instantiating and Invoking a Server-Activated Object
At this stage, you have a remotable object as well as a remoting server ready. In this section, I'll show you how to create a remoting client and use it to send messages to the remoting server to activate the remote object. In order to achieve this, the remoting client needs to take the following steps:
Create and register a client channel that is used by the remoting framework to send messages to the remoting server. The type of the channel used by the client should be compatible with the channel used by server. The following examples show how to create a TCP client channel and an HTTP client channel:
' Create and register a TCP client channel
Dim channel As TcpClientChannel = _
New TcpClientChannel()
ChannelServices.RegisterChannel(channel)
' Create and register a HTTP client channel
Dim channel As HttpClientChannel = _
New HttpClientChannel()
ChannelServices.RegisterChannel(channel)TIP
Client Channel Registration You do not specify a port number when you register the client channel. The port number is instead specified at the time you register the remote class in the client's domain.
Register the remotable class as a valid type in the client's application domain. This registration is performed using the RegisterWellKnownClientType() method of the RemotingConfiguration class as shown here:
' Register the remote class as a valid
' type in the client's application domain
RemotingConfiguration.RegisterWellKnownClientType( _
GetType(DbConnect), "tcp://localhost:1234/DbConnect")Here, the first parameter is the type of the remotable class. The second parameter specifies the uniform resource identifier (URI) through which the server publishes the location of the remote object. Localhost maps to your local development machine. If the remote object is on some other computer, you'll replace localhost with the name of the computer.
TIP
Instantiating a Server-Activated Object You can only instantiate an SAO at client side using its default constructor.
Instantiate the SAO on the server. You can only use the default constructor.
' Instantiate the remote object
DbConnect dbc = new DbConnect()I'll demonstrate the preceding steps in Step by Step 3.3. In this example, I'll create the client program as a Windows application that accepts a SQL statement from the user and passes it to the remotable object. The rows returned by the remotable object are displayed in a DataGrid control.
STEP BY STEP 3.3: Instantiating and Invoking a Server-Activated Object
Add a new Visual Basic .NET Windows Application named StepByStep3-3 to the solution.
Add references to the .NET assembly System.Runtime.Remoting and the project StepByStep3-1 (the remotable class assembly).
In the Solution Explorer, delete the default Form1.vb. Add a new form named DbConnectClient.vb. Set the new form as the Startup object for the project.
Add the following directives to the form's module:
Imports System.Runtime.Remoting
Imports System.Runtime.Remoting.Channels
Imports System.Runtime.Remoting.Channels.Tcp
Imports StepByStep3_1Place two GroupBox controls, a TextBox control (txtQuery), a Button control (btnExecute) and a DataGrid control (dgResults) on the form. Set the Multiline property of txtQuery to True.
Add the following code to the form directly after the designer-generated code:
' Declare a Remote object
Dim dbc As DbConnectDouble-click the form and add the following code in the Load event handler:
Private Sub DbConnectClient_Load( _
ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
' Register a TCP client channel
Dim channel As TcpClientChannel = _
New TcpClientChannel()
ChannelServices.RegisterChannel(channel)
' Register the remote class as a valid
' type in the client's application domain
RemotingConfiguration. _
RegisterWellKnownClientType( _
GetType(DbConnect), _
"tcp://localhost:1234/DbConnect")
' Instantiate the remote class
dbc = New DbConnect()
End SubDouble-click the Button control and add the following code in the Click event handler:
Private Sub btnExecute_Click( _
ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btnExecute.Click
Try
' Invoke a method on the remote object
Me.dgResults.DataSource = _
dbc.ExecuteQuery(Me.txtQuery.Text)
dgResults.DataMember = "Results"
Catch ex As Exception
MessageBox.Show(ex.Message, _
"Query Execution Error")
End Try
End SubRight-click on the name of the solution in the Solution Explorer window and select Properties. This opens the Solution Property Pages dialog box. In the dialog box, select the Multiple Startup Projects check box, select the action Start for StepByStep3-2 and StepByStep3-3, and set the action to None for other projects as shown in Figure 3.6. Make sure that StepByStep3-2 is placed above StepByStep3-3. If it isn't already there, click the Move Up and Move Down buttons to get the right order.
Build the project. Select Debug, Start to run the project. You should see a command window displaying a message that the server is started in the SingleCall mode.
Shortly afterward, you'll see a Windows form for the client program. Enter a query in the text box and click the Execute Query button. The client invokes a method on the remote object and binds the results from the remote method to the DataGrid control.
Unless you have spent the last two years in hibernation, you must already be aware of XML Web Services and its powers. Despite all the attention Web Services have received as an ultimate solution to distributed computing, let us face the ground reality. There are still thousands of applications running on intranets and there would be thousands more that would be developed in future.
The goal of these applications is not to carry out cross–platform communication across heterogeneous systems (which is the strength of Web Services). In such cases there is no point in building these applications as Web Services as they may not be able to provide the desired performance and capabilities. Instead using .NET Remoting to carry out client–server communication would be an excellent solution.
Application Boundaries
An application boundary defines the scope of an application. It encompasses various resources critical to an application's execution, such as address space, executable code and the data used by the application. A typical multiprogramming execution environment, such as Windows, uses application boundaries to protect one application from affecting the execution of another application.
In this section, you'll learn about the application boundaries supplied by Windows and the .NET Framework. You'll understand how application boundaries protect applications from poorly designed or faulty code. You'll also learn how application boundaries make it difficult to design applications that want to communicate beyond application boundaries.
Process Boundary
A process is an application under execution. Windows isolates processes from each other to ensure that code running in one process cannot adversely affect other processes. Windows achieves this isolation by creating a process boundary. A process boundary ensures that
Each process has its own virtual address space, executable code, and data.
A Windows process cannot directly access the code or data of another Windows process.
A Windows process runs only one application, so if an application crashes, it does not affect other applications.
Process boundaries are a good thing because they allow processes to coexist. However, it takes lot of system resources to create, monitor, and terminate a process. In addition, when the processor switches between the processes, the processor must save and reset the execution context of the processes. Often an application would involve several short-lived processes, which require the system to spend a lot of resources just for process management.
Application Domain Boundary
The Common Language Runtime (CLR) provides a managed execution environment for the .NET applications. The managed execution environment provides various services to the executing code; including cross-language integration, code access security, object lifetime management, and debugging and profiling support. This is why code executed by the CLR is also known as managed code.
Unlike Windows, the CLR can verify the type-safety of programs to guarantee that a program does not request resources outside of its own boundary. The characteristics of the CLR help provide isolation between running programs at a lower cost than the process boundary.
Instead of a process, the basic unit of isolation for running applications in the CLR is an application domain. An application domain (also known as an AppDomain) is the smallest execution unit for a .NET application. The CLR allows several application domains to run within a single Windows process and still provides the same level of isolation between applications as provided by a Windows process.
The application domains achieve isolation through application domain boundaries, which ensure that
Each application domain contains its own set of code, data, and configuration settings.
An application domain cannot directly access the code or data structures of another application domain.
Code running in one application domain cannot affect other application domains. The CLR can terminate an application domain without stopping the entire process.
Creating, monitoring, and maintaining an application domain uses fewer resources than performing the same operations with a process. In addition, the capability of an application domain to run multiple applications within the same process reduces the overhead of process switching. Thus, application domains increase the performance of the applications.
You can create an application domain in a program using the AppDomain class of System namespace. However, in most cases the application domains are created and managed by the runtime hosts that execute your code. Runtime hosts provide the environment to run managed code on behalf of the user. When you install the .NET Framework, you get three runtime hosts already configured—the Windows shell, ASP.NET, and Internet Explorer.
Distributed Applications
From the previous sections, you can see that both process and application domains provide a closely protected environment. As a result, objects in a process or an application domain cannot directly talk to objects in another process or application domain.
However, in the increasingly connected world, enterprises and users demand distributed applications. Distributed applications allow objects to talk across process boundaries. Often, distributed applications also meet the following objectives:
Establishes communication between objects that run in different application domains and processes whether on the same computer or across the Internet.
Enables enterprise application integration by establishing communication between objects that run on heterogeneous architectures.
Enables application availability by making sure that portions of an application continue to run even if some components are busy or have failed.
Provides increased security and scalability by dividing the application into several layers (or tiers).
Evolution of Distributed Applications
A well-designed distributed application has the potential to be more connected, more available, more scalable, and more robust than an application in which all components run on a single computer. This is a desirable model for an enterprise application.
Several efforts have been made to design frameworks for developing distributed applications. A few well-known frameworks are Distributed Computing Environment/Remote Procedure Calls (DEC/RPC), Microsoft Distributed Component Object Model (DCOM), Common Object Request Broker Architecture (CORBA), and Java Remote Method Invocation (RMI). Some of these implementations are widely deployed in enterprises.
However, modern business requirements are different from earlier days. Today, businesses seek solutions that can be developed rapidly, that integrate well with their legacy applications, and that interoperate well with their business partners. Each of the previously mentioned technologies failed to satisfy one or more of these requirements.
In 2000, Microsoft introduced the .NET Framework for designing next-generation, distributed applications. As you'll explore more in this book, the .NET Framework is specifically targeted to meet the needs of modern business whether the need is rapid development, integration, or interoperability.
Developing Distributed Applications Using the .NET Framework
The .NET Framework provides various mechanisms to support distributed application development. Most of this functionality is present in the following three namespaces of the Framework Class Library (FCL):
The System.Net Namespace—This namespace includes classes to create standalone listeners and custom protocol handlers to start from scratch, as well as to create your own framework for developing a distributed application. Working with the System.Net namespace directly requires a good understanding of network programming.
The System.Runtime.Remoting Namespace—This namespace includes the classes that constitutes the .NET remoting framework. The .NET remoting framework enables communication between objects living in different application domains whether or not they are on the same computer. Remoting provides an abstraction over the complexities of network programming and exposes a simple mechanism for interapplication domain communication. The key objectives of .NET remoting are flexibility and extensibility.
The System.Web.Services Namespace—This namespace includes the classes that constitute the ASP.NET Web services framework. ASP.NET Web services enable objects living in different application domains to exchange messages using standard protocols such as HTTP and SOAP. ASP.NET Web services, when compared to remoting, provide a much higher level of abstraction and simplicity. The key objectives of ASP.NET Web services are ease of use and interoperability with other systems.
Both .NET remoting and ASP.NET Web services provide a complete framework for designing distributed applications. Most programmers will use either .NET remoting or ASP.NET Web services instead of building a distributed programming framework from scratch using the System.Net namespace classes.
The functionality offered by .NET Remoting and ASP.NET Web services appears very similar to each other. In fact, ASP.NET Web services are actually built on the .NET Remoting infrastructure. It is also possible to design Web services using .NET remoting. Given the amount of similarity, how do you choose one over another in your project? Simply put, the decision depends on the type of application you want to create. You'll use
.NET Remoting when both of the endpoints (client and server) of a distributed application are in your control. This might be a case when an application has been designed for use within a corporate network.
ASP.NET Web services when one of the endpoints of a distributed application is not in your control. This might be a case when your application is interoperating with your business partner's application.
.NET Remoting Architecture
.NET remoting enables objects in different application domains to talk to each other. The real strength of remoting is in enabling communication between objects when their application domains are separated across the network. In this case, remoting transparently handles details related to network communication.
Before getting into details, let's first answer a basic question—How can remoting establish cross-application domain communication when an application domain does not allow direct calls across its boundary?
Remoting takes an indirect approach to application domain communication by creating proxy objects . Both application domains communicate with each other using the following steps:
When a client object wants to create an instance of the server object, the remoting system at the client side instead creates a proxy of the server object. The proxy object lives at the client but behaves just like the remote object; this leaves the client with the impression that the server object is in the client's process.
In a simplified view of .NET remoting, note that the client and server communicate indirectly through a proxy object.
When the client object calls a method on the server object, the proxy passes the call information to the remoting system on the client. This remoting system in turn sends the call over the channel to the remoting system on the server.
The remoting system on the server receives the call information and, on the basis of it, invokes the method on the actual object on the server (creating the object if necessary).
The remoting system on the server collects all the results of the method invocation and passes them through the channel to the remoting system on the client.
The remoting system at the client receives the response of the server and returns the results to the client object through the proxy.
The process of packaging and sending method calls among the objects across the application boundaries via serialization and deserialization, as shown in the preceding steps, is also known as marshalling.
Now that you have a basic idea of how .NET remoting works, its time to get into details. In the next few sections, I'll explain the various key components and terminology of .NET remoting.
Object Marshalling
Remotable objects are objects that can be marshalled across the application domains. In contrast, all other objects are known as non-remotable objects. There are two types of remotable objects:
Marshal-by-value (MBV) Objects—These objects are copied and passed out of the server application domain to the client application domain.
Marshal-by-reference (MBR) Objects—These objects are accessed on the client side using a proxy. The client just holds a reference to these objects.
Marshal-by-Value Objects
MBV objects reside on the server. However, when the client invokes a method on the MBV object, the MBV object is serialized, transferred over the network, and restored on the client as an exact copy of the server-side object. The method is then invoked directly on the client. When this happens, the MBV object is no longer a remote object. Any method calls to the object do not require any proxy object or marshalling because the object is locally available.
The MBV objects can provide faster performance by reducing the number of network roundtrips, but in the case of large objects, the time taken to transfer the serialized object from the server to the client can be very significant. Further, MBV objects do not allow you the flexibility to run the remote object in the server environment.
A MBV object can be created by declaring a class with the Serializable attribute; for example
' Define a MBV remoting object
Public Class MyMBVObject
' Implementation details
End ClassIf a class needs to control its own serialization, it can do so by implementing the ISerializable interface as shown here:
Imports System.Runtime.Serialization
' Define a MBV remoting object
Public Class MyMBVObject
Implements ISerializable
' Class details ...
'Implement custom serialization here
Public Sub GetObjectData( _
ByVal info As SerializationInfo, _
ByVal context As StreamingContext)
' Serialization details ...
End Sub
End ClassMarshal-by-Reference Objects
MBR objects are remote objects. They always reside on the server, and all methods invoked on these objects are executed at the server side. The client communicates with the MBR object on the server using a local proxy object that holds the reference to the MBR object.
Although the use of MBR objects increases the number of network roundtrips, they are a good choice when the objects are prohibitively large or when the functionality of the object is only available in the server environment on which it is created.
An MBR object can be created by deriving from the System.MarshalByRefObject class; for example,
' Define a MBR remoting object
Public Class MyMBRObject
Inherits MarshalByRefObject
' Class details ...
End ClassChannels
Create and consume a .NET Remoting object: Select a channel protocol and a formatter. Channel protocols include TCP and HTTP. Formatters include SOAP and binary.
Channels are the objects that transport messages across remoting boundaries such as application domains, processes, and computers. When a client calls a method on a remote object, the details of the method call are transported to the remote object through a channel. Any results returned from the remote object are communicated back to the client again through the same channel.
The .NET remoting framework ensures that before a remote object can be called, it has registered at least one channel with the remoting system on the server. Similarly, the client object should specify a channel before it can communicate with a remote object. If the remote object offers more than one channel, the client can connect using the channel that best suits its requirements.
A channel has two endpoints. The channel object at the receiving end of a channel (the server) listens to a particular protocol using the specified port number, whereas the channel object at the sending end of the channel (the client) sends information to the receiving end using the protocol and port number specified by the channel object on the receiving end.
Formatters
Formatters are the objects used to encode and serialize data into messages before they are transmitted over a channel.
To participate in the .NET remoting framework, a formatter class must implement the IFormatter interface. The .NET Framework packages two formatter classes for common scenarios—the BinaryFormatter class and the SoapFormatter class. If you want to use a different formatter, you can define your own formatter class by implementing the IFormatter interface.
The SOAP Formatter
SOAP (Simple Object Access Protocol) is a relatively straightforward, XML-based protocol for exchanging types and messages between applications. SOAP is an extensible and modular protocol; it is not bound to a particular transport mechanism such as HTTP or TCP.
The SOAP formatter is implemented in the SoapFormatter class of the System.Runtime.Serialization.Formatters.Soap namespace.
SOAP formatting is an ideal way of communicating between applications that use incompatible architectures. However, SOAP is very verbose. SOAP messages require more bytes to represent data than the equivalent binary messages.
The Binary Formatter
Unlike SOAP, the binary format used by the .NET Framework is proprietary and can be understood only within .NET applications. However, as compared to SOAP, the binary format of representing messages is very compact and efficient.
The binary formatter is implemented in the BinaryFormatter class of the System.Runtime.Serialization.Formatters.Binary namespace.
Channels and Formatters
The HTTP channel uses the SOAP formatter as its default formatter to transport messages to and from the remote objects. The HTTP channel uses SoapClientFormatterSinkProvider and SoapServerFormatterSinkProvider classes to serialize and deserialize messages using SoapFormatter. You can create industry-standard XML Web services by using the SOAP formatter with the HTTP channel.
The TCP channel uses the binary format by default to transport messages to and from the remote object. The TCP channel uses BinaryClientFormatterSinkProvider and BinaryServerFormatterSinkProvider classes to serialize and deserialize messages using BinaryFormatter.
However, channels are configurable. You can configure the HTTP channel to use the binary formatter or a custom formatter instead of the SOAP formatter. Similarly, the TCP channel can be configured to use the SOAP formatter or a custom formatter instead of the binary formatter.
Figure 3.2 compares the various combinations of channels and formatters on the scale of efficiency and compatibility. The protocols at the top of the list are the most efficient, while those at the bottom of the list are most interoperable. You can use this information to decide which combination of channel and formatter you would choose in a given scenario.
Remote Object Activation
Between the two types of objects that you have seen (MBV objects and MBR objects), only MBR objects can be activated remotely. No remote activation is needed in the case of MBV objects because the MBV object itself is transferred to the client side.
TIP
Remotable Members An MBR object can remote the following types of members:
Non-static public methods
Non-static public properties
Non-static public fields
Based on the activation mode, an MBR object is classified into one of the following two categories:
Server-activated objects
Client-activated objects
Server-Activated Objects
Server-activated objects (SAO) are those remote objects whose lifetime is directly controlled by the server.
When a client requests an instance of a server-activated object, a proxy to the remote object is created in the client's application domain. The remote object is only instantiated (or activated) on the server when the client calls a method on the proxy object.
Server-activated objects provide limited flexibility because they can only be instantiated using their default (parameter-less) constructors.
NOTE
Well-Known Objects Remote objects activated in SingleCall or Singleton activation mode are also known as well-known objects.
There are two possible activation modes for a server-activated object:
SingleCall activation mode
Singleton activation mode
SingleCall Activation Mode
In the SingleCall activation mode, an object is instantiated for the sole purpose of responding to just one client request. After the request is fulfilled, the .NET remoting framework deletes the object and reclaims its memory.
Objects activated in the SingleCall mode are also known as stateless because the objects are created and destroyed with each client request; therefore, they do not maintain state across requests. This behavior of SingleCall mode allows for greater server scalability as an object consumes server resources only for a small period, therefore allowing the server to allocate resources to other objects.
The SingleCall activation mode is a desired solution when
The overhead of creating an object is not significant.
The object is not required to maintain its state.
The server needs to support a large number of requests for the object.
The object needs to be supported in a load-balanced environment.
TIP
Load-Balancing and SingleCall Activation Sometimes to improve the overall efficiency of an application, it might be hosted on multiple servers that share the incoming requests to the application. In this case, a request can go to any of the available servers for processing. This scenario is called a load-balancing environment.
Because the SingleCall objects are stateless, it does not matter which server processes requests for such objects. For this reason, SingleCall activation is ideally suited for load-balanced environments.
Common scenarios of the SingleCall activation mode are those applications in which the object is required by the client to do a small amount of work and then the object is no longer required. Some common examples are retrieving the inventory level for an item, displaying tracking information for a shipment, and so on.
Singleton Activation Mode
In the Singleton activation mode, at most there will be one instance of the remote object regardless of the number of clients accessing it.
A Singleton-mode object can maintain state information across method calls. For this reason, such objects are also sometimes known as stateful objects. The state maintained by the Singleton-mode object is globally shared by all of its clients. This generally means that you should not store any state in Singleton-mode objects. But there are circumstances (such as keeping track of usage statistics) in which it can make sense to store shared state.
A Singleton object does not exist on the server forever. Its lifetime is determined by the lifetime lease of the object. I'll discuss lifetime leases later in the chapter.
A Singleton object is a desired solution when
The overhead of creating an object is substantial.
The object is required to maintain its state over a prolonged period.
Several clients need to work on the shared state.
Singleton activation mode is useful in scenarios such as in a chat server in which multiple clients talk to the same remote object and share data between one another through this object.
Client-Activated Objects
Client-activated objects (CAO) are those remote objects whose lifetime is directly controlled by the client. This is in direct contrast with SAOs, where the server, not the client, has the complete control over the lifetime of the objects.
Client-activated objects are instantiated on the server as soon as the client requests the object to be created. Unlike an SAO, a CAO does not delay the object creation until the first method is called on the object.
A CAO can be created using any of the available constructors for the class. A typical CAO activation involves the following steps:
When the client attempts to create an instance of the server object, an activation request message is sent to the remote server.
The server then creates an instance of the requested class using the specified constructor and returns an ObjRef object to the client application that invoked it. The ObjRef object contains all the required information to generate a proxy object that is capable of communicating with a remote object.
The client uses the ObjRef object to create a proxy for the server object on the client side.
An instance of a CAO serves only the client responsible for its creation, and the CAO doesn't get discarded with each request. For this reason, a CAO can maintain state with each client that it is serving, but unlike the Singleton SAO, different CAOs cannot share a common state.
The lifetime of a CAO is determined using lifetime leases. I'll talk more about this topic shortly in a section titled "Lifetime Leases."
A CAO is a desired solution when
The clients want to maintain a private session with the remote object.
The clients want to have more control over how the objects are created and how long they will live.
A CAO is useful in scenarios such as entering a complex purchase order in which multiple roundtrips are involved and clients want to maintain their own private state with the remote object.
Comparing the Object Activation Techniques
Based on the discussions in the previous section, the various object activation techniques can be compared as shown in Figure 3.3.
The SingleCall server activation has maximum scalability because such objects occupy server resources for the minimum amount of the time. This enables the server to allocate its resources between a large numbers of clients.
On the other hand, the client activation of remote objects offers maximum flexibility because you have complete control over the construction and lifetime of the remote object.
Applying .NET Remoting
Applying .NET Remoting
So far, I have discussed the architecture and various concepts related to the .NET remoting. In this section, you will learn how to apply these concepts to see remoting in action. In particular, you will learn how to
Create a remotable class.
Create a Server-activated object.
Create a Client-activated object.
Use configuration files to configure the remoting framework.
Use interface assemblies to compile remoting clients.
Creating a Remotable Class
Creating a remotable class is simple. All you need to do is to inherit a class from the MarshalByRefObject class. Step By Step 3.1 creates a remotable class named DbConnect. This class connects to a specified SQL Server database and allows you to execute a SELECT SQL statement using its ExecuteQuery() method.
STEP BY STEP 3.1: Creating a Remotable Class
Launch Visual Studio .NET. Select File, New, Blank Solution, and name the new solution 310C03. Click OK.
Add a new Visual Basic .NET Class library named StepByStep3-1 to the solution.
In the Solution Explorer, rename the default Class1.vb to DbConnect.vb.
Open the DbConnect.vb class and replace the code with the following code:
Imports System
Imports System.Data
Imports System.Data.SqlClient
' Marshal-by-Reference Remotable Object
Public Class DbConnect
Inherits MarshalByRefObject
Private sqlconn As SqlConnection
' Default constructor connects to the Northwind
' database
Public Sub New()
sqlconn = New SqlConnection( _
"data source=(local);" & _
"initial catalog=Northwind;" & _
"integrated security=SSPI")
Console.WriteLine( _
"Created a new connection " & _
"to the Northwind database")
End Sub
' Parameterized constructor connects to the
' specified database
Public Sub New(ByVal DbName As String)
sqlconn = New SqlConnection( _
"data source=(local);" & _
"initial catalog=" & DbName & ";" & _
"integrated security=SSPI")
Console.WriteLine( _
"Created a new connection " & _
"to the " & DbName & " database")
End Sub
Public Function ExecuteQuery( _
ByVal strQuery As String) As DataSet
Console.Write("Starting to execute " & _
"the query...")
' Create a SqlCommand to represent the query
Dim sqlcmd As SqlCommand = _
sqlconn.CreateCommand()
sqlcmd.CommandType = CommandType.Text
sqlcmd.CommandText = strQuery
' Create a SqlDataAdapter object
' to talk to the database
Dim sqlda As SqlDataAdapter = _
New SqlDataAdapter()
sqlda.SelectCommand = sqlcmd
' Create a DataSet to hold the results
Dim ds As DataSet = New DataSet()
Try
' Fill the DataSet
sqlda.Fill(ds, "Results")
Catch ex As Exception
Console.WriteLine(ex.Message, _
"Error executing query")
End Try
Console.WriteLine("Done.")
ExecuteQuery = ds
End Function
End ClassSelect Build, Build StepByStep3-1. This step packages the remotable class into the file StepByStep3-1.dll, which is located in the bin or directory of your project. You can navigate to it through the Solution Explorer: Just select the project and click the Show All Files button in the Solution Explorer toolbar.
You've now created a remotable class, but it cannot yet be directly called from client application domains. For a remotable class to be activated, you need to connect the class to the remoting framework. You'll learn how to do that in the next section.
Creating a Server-Activated Object
A remotable class is usually connected with the remoting framework through a separate server program. The server program listens to the client request on a specified channel and instantiates the remote object or invokes calls on it as required.
It is a good idea to keep the remotable class and server program separate; this enables the design to be modular and the code to be reusable.
In this section, I'll show you how to create a remoting server. Here's an overview of the steps that the remoting server must take.
Create a server channel that listens on a particular port to the incoming object activation requests from other application domains. The following code segment shows how to create a TCP server channel and an HTTP server channel:
' Register a TCP server channel on port
Dim channel As TcpServerChannel = _
New TcpServerChannel(1234)
' Register a HTTP server channel on port
Dim channel As HttpServerChannel = _
New HttpServerChannel(1234)Register the channel with the remoting framework. This tells the framework which requests should be directed to this particular server. This registration is performed through the RegisterChannel() method of the ChannelServices class:
' Register the channel with remoting framework
ChannelServices.RegisterChannel(channel)Register the remotable class with the remoting framework. This tells the framework which classes this particular server can create for remote clients. For a server-activated object, this registration is performed using the RegisterWellKnownServiceType() method of the RemotingConfiguration class, as shown here:
' Register a remote object with the remoting framework
RemotingConfiguration.RegisterWellKnownServiceType( _
GetType(DbConnect), "DbConnect", _
WellKnownObjectMode.SingleCall)Here, the first parameter is the type of the remotable class. The second parameter specifies the uniform resource identifier (URI) through which the server publishes the location of the remote object. The last parameter specifies the activation mode. The activation mode can be one of the two possible values of the WellKnownObjectMode enumeration—SingleCall or Singleton.
TIP
Accessing an Object Through Multiple Channels From steps 2 and 3, you can note that the channel registration and the remote object registration are not related. In fact, a remote object can be accessed through all registered channels.
With the channel and class both registered, the remoting server is ready to go. The remoting framework will direct all requests for that class via that channel to the registered server.
As I discussed, earlier, an SAO can be activated in two different modes—SingleCall and Singleton. In the next few sections, I'll cover how to create a remoting server for activating objects in each of these modes. I'll also tell the story on the other side of the channel; that is, how to connect the client program to the remoting framework so that it can instantiate the SAO and call methods on it.
Registering a Remotable Class As a Server-Activated Object Using the SingleCall Activation Mode
In this section, I'll demonstrate how to create a server that exposes the remotable class through the remoting framework. The server process here will be a long running user interface-less process that will continue to listen for incoming client requests on a channel.
Ideally, you should write this type of server program as a Windows service or use an existing Windows service such as Internet Information Services (IIS) to work as a remoting server. But I have chosen to write the server program as a console application mainly because I'll use the console Window to display various messages that will help you understand the workings of the remoting server.
Later in this chapter, in the section "Using IIS As an Activation Agent," I'll cover how to use IIS as a remoting server. I'll talk about Windows services in Chapter 6, "Windows Services."
STEP BY STEP 3.2: Registering a Server-Activated Object Using the SingleCall Activation Mode
Add a new Visual Basic .NET Console application named StepByStep3-2 to the solution.
In the Solution Explorer, right-click the project StepByStep3-2 and select Add Reference from the context menu. In the Add Reference dialog box (see Figure 3.4), select the .NET tab, select the System.Runtime.Remoting component from the list view, and click the Select button. Now select the Projects tab, select the Project named StepByStep3-1 (which contains the remotable object) from the list view, and click the Select button. Both the selected projects then appear in the Selected Components list, as shown in Figure 3.4. Click OK.
In the Solution Explorer, rename the default Module1.vb module to DbConnectSingleCallServer.vb. Open the file and change the name of the module to DbConnectSingleCallServer in the module declaration.
NOTE
Namespace Naming Note that although the project is named StepByStep3-1, the corresponding namespace is named StepByStep3_1. That's because the .NET Framework considers a dash to be an illegal character in a namespace name.
Add the following Imports directives above the module declaration:
Imports StepByStep3_1
Imports System.Runtime.Remoting
Imports System.Runtime.Remoting.Channels
Imports System.Runtime.Remoting.Channels.TcpAdd the following code in the Main() procedure:
Public Sub Main()
' Create and Register a TCP server channel
' that listens on port
Dim channel As TcpServerChannel = _
New TcpServerChannel(1234)
ChannelServices.RegisterChannel(channel)
' Register the service that publishes
' DbConnect for remote access in SingleCall mode
RemotingConfiguration. _
RegisterWellKnownServiceType( _
GetType(StepByStep3_1.DbConnect), "DbConnect", _
WellKnownObjectMode.SingleCall)
Console.WriteLine("Started server in the " & _
"SingleCall mode")
Console.WriteLine("Press to terminate " & _
"server...")
Console.ReadLine()
End SubRight-click on the StepByStep3-2 project in the Solution Explorer and select Properties. Change the Startup object to DbConnectSingleCallServer.
Build the project. This step creates a remoting server that is capable of registering the StepByStep3_1.DbConnect class for remote invocation using the SingleCall activation mode.
Step by Step 3.2 uses a receiver TCP channel (TcpServerChannel) to register a remotable class with the remoting framework. However, converting this program to use HTTP channel is not difficult—you just need to change all instances of Tcp to Http.
Step By Step 3.2 creates a remoting host that listens on port 1234. This is an arbitrary port number that might or might not work on your computer. A good idea is to check whether a port is already in use by some other application before running this program. You can do this from the command line on a particular computer by using the Windows netstat command.
This suggestion works only in a test scenario. It is not reasonable to instruct a customer to check whether the port is available before he starts the application. If the application will run entirely on your company's network, you can safely use a port in the private port range of 49152 through 65535—provided, of course, that the port number you choose is not used by any other internal application. In case you are distributing the application, you should get a port number registered with the IANA (Internet Assigned Numbers Authority). You can see a list of already assigned port numbers at http://www.iana.org/assignments/port-numbers.
Instantiating and Invoking a Server-Activated Object
At this stage, you have a remotable object as well as a remoting server ready. In this section, I'll show you how to create a remoting client and use it to send messages to the remoting server to activate the remote object. In order to achieve this, the remoting client needs to take the following steps:
Create and register a client channel that is used by the remoting framework to send messages to the remoting server. The type of the channel used by the client should be compatible with the channel used by server. The following examples show how to create a TCP client channel and an HTTP client channel:
' Create and register a TCP client channel
Dim channel As TcpClientChannel = _
New TcpClientChannel()
ChannelServices.RegisterChannel(channel)
' Create and register a HTTP client channel
Dim channel As HttpClientChannel = _
New HttpClientChannel()
ChannelServices.RegisterChannel(channel)TIP
Client Channel Registration You do not specify a port number when you register the client channel. The port number is instead specified at the time you register the remote class in the client's domain.
Register the remotable class as a valid type in the client's application domain. This registration is performed using the RegisterWellKnownClientType() method of the RemotingConfiguration class as shown here:
' Register the remote class as a valid
' type in the client's application domain
RemotingConfiguration.RegisterWellKnownClientType( _
GetType(DbConnect), "tcp://localhost:1234/DbConnect")Here, the first parameter is the type of the remotable class. The second parameter specifies the uniform resource identifier (URI) through which the server publishes the location of the remote object. Localhost maps to your local development machine. If the remote object is on some other computer, you'll replace localhost with the name of the computer.
TIP
Instantiating a Server-Activated Object You can only instantiate an SAO at client side using its default constructor.
Instantiate the SAO on the server. You can only use the default constructor.
' Instantiate the remote object
DbConnect dbc = new DbConnect()I'll demonstrate the preceding steps in Step by Step 3.3. In this example, I'll create the client program as a Windows application that accepts a SQL statement from the user and passes it to the remotable object. The rows returned by the remotable object are displayed in a DataGrid control.
STEP BY STEP 3.3: Instantiating and Invoking a Server-Activated Object
Add a new Visual Basic .NET Windows Application named StepByStep3-3 to the solution.
Add references to the .NET assembly System.Runtime.Remoting and the project StepByStep3-1 (the remotable class assembly).
In the Solution Explorer, delete the default Form1.vb. Add a new form named DbConnectClient.vb. Set the new form as the Startup object for the project.
Add the following directives to the form's module:
Imports System.Runtime.Remoting
Imports System.Runtime.Remoting.Channels
Imports System.Runtime.Remoting.Channels.Tcp
Imports StepByStep3_1Place two GroupBox controls, a TextBox control (txtQuery), a Button control (btnExecute) and a DataGrid control (dgResults) on the form. Set the Multiline property of txtQuery to True.
Add the following code to the form directly after the designer-generated code:
' Declare a Remote object
Dim dbc As DbConnectDouble-click the form and add the following code in the Load event handler:
Private Sub DbConnectClient_Load( _
ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
' Register a TCP client channel
Dim channel As TcpClientChannel = _
New TcpClientChannel()
ChannelServices.RegisterChannel(channel)
' Register the remote class as a valid
' type in the client's application domain
RemotingConfiguration. _
RegisterWellKnownClientType( _
GetType(DbConnect), _
"tcp://localhost:1234/DbConnect")
' Instantiate the remote class
dbc = New DbConnect()
End SubDouble-click the Button control and add the following code in the Click event handler:
Private Sub btnExecute_Click( _
ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btnExecute.Click
Try
' Invoke a method on the remote object
Me.dgResults.DataSource = _
dbc.ExecuteQuery(Me.txtQuery.Text)
dgResults.DataMember = "Results"
Catch ex As Exception
MessageBox.Show(ex.Message, _
"Query Execution Error")
End Try
End SubRight-click on the name of the solution in the Solution Explorer window and select Properties. This opens the Solution Property Pages dialog box. In the dialog box, select the Multiple Startup Projects check box, select the action Start for StepByStep3-2 and StepByStep3-3, and set the action to None for other projects as shown in Figure 3.6. Make sure that StepByStep3-2 is placed above StepByStep3-3. If it isn't already there, click the Move Up and Move Down buttons to get the right order.
Build the project. Select Debug, Start to run the project. You should see a command window displaying a message that the server is started in the SingleCall mode.
Shortly afterward, you'll see a Windows form for the client program. Enter a query in the text box and click the Execute Query button. The client invokes a method on the remote object and binds the results from the remote method to the DataGrid control.


32 Comments:
You have very nice and useful source. Krosavcheg!
louis vuitton replica sunglasses
how to get cash advance from your paycheck
fast loan payday quick
apply canada in loan personal quick
quick loan approval
payday paycheck loan
advance cash instant online payday
advance lender loan payday
cash emergency fast loan loan loan payday quick
24 hour payday loan
score and more free credit report
Good Bye!
By
Anonymous, at 7:11 PM
Wow, man! Cool site!
buy generic phentermine
buy cod online pay tramadol
buy cod soma
cialis tadalafil uk
buy cheap tadalafil
atarax tablet
cheap phentermine no rx
With best regards...
By
Anonymous, at 8:09 AM
"I have been using Advanced Gain Pro for 3 months now and I must say I'm simply amazed. I really didn't think the product would have this many benefits. I really only purchased the pills to help the reliability of my erections. But to my surprise every aspect of my penis and sex life has improved. I have larger, harder erections easily, and I can really satisfy my girlfriend fully now."
Dexter, Chicago
The most advanced PE pill available today
________________________________
Our others products, more info here:
Ultra Allure Pheromones
Anatrim
By
Anonymous, at 1:03 PM
Hello, very nice site! Please also visit my homepages:
safe effective diet pills
how to lose body fat and build muscle
See you tomorrow!
By
Anonymous, at 8:42 PM
It's very interesting!
zithromax 1g
zithromax
zithromax z pack
zithromax used for treating
zithromax as treatment for chlamydia
zithromax dosing instructions
zithromax medicine
zithromax as for treatment for chlamydia
zithromax dosage
alcohol and zithromax
zithromax no perscription
side effects of zithromax
zithromax azithromycin
zithromax no prescription
antibiotic zithromax
zithromax side effects
zithromax z-pak
zithromax 3 week course
Bye!
By
Anonymous, at 10:29 PM
Cute, very cute... Thanks man!
effexor xr
effexor xr withdrawal
is effexor xr a good drug
effexor xr withdraw symptoms
effexor xr side effects
effexor xr weight loss
effexor xr withdrawal symptoms
effexor xr and eye problems
effexor xr withdrawals
generic effexor xr
effexor xr online
effexor xr 75mg side effects
alcohol and effexor xr
effexor xr generic
antidepressant effexor xr
effexor xr dosage
side effects of effexor xr
buy effexor xr
cheap effexor xr
effexor xr 37.5
effexor xr discount
effexor xr hearing loss
effexor xr treats depression
Good Bye!
By
Anonymous, at 12:23 AM
Nice plagiarism! I guess you figure that no one else reads books; specifically MCAD/MCSD Training Guide (70-310): Developing XML Web Services and Server Components with Visual Basic® .NET and the .NET Framework
Why listen to this douche when you can get it straight from the horses mouth (you know, the one that copyrighted this material)?
For the original material please visit:
http://www.informit.com/articles/article.asp?p=31446&seqNum=5&rl=1
By
Anonymous, at 1:03 PM
Cool site! Lets links exchange? :)
penis enlargement pill
best penis enlargement pill
natural penis enlargement pill
penis enlargement pill review
do penis enlargement pill work
enlargement penis pills
buy penis pills
cheap penis enlargement pill
penis enlargement pill
penis enlargement pill product
herbal penis enlargement pill
cheapest penis enlargement pill
penis enlargement pills
buy penis enlargement pill
natural penis enlargement
penis enlargement pills online
natural penis enlargement pill
penis enlargement drug
penis enlargement natural
Good Bye!
By
Anonymous, at 9:39 AM
[url]http://freefurniture.php1h.com/furnitures[/url]
furnitures
[url]http://freefurniture.php1h.com/ashley_bedroom[/url]
ashley bedroom
[url]http://freefurniture.php1h.com/modern_furniture[/url]
modern furniture
[url]http://freefurniture.php1h.com/ashley_furniture[/url]
ashley furniture
By
Anonymous, at 8:56 PM
I play in On line Casino here. Its interesting.
[url=http://casino.rxworlddata.info][b]casino[/b][/url]
[url=http://casino.rxtvinfo.info]online casino[/url]
[url=http://webraindor.info/wiki/phentermine][b]phentermine[/b][/url]
By
Anonymous, at 9:56 AM
nice site for more books I have some more gifts..
Reference books
Books
Kitaben
books
Reference Books
tutorials
rapidshare tutorials
rapidshare books
MZWorld
Upload Books
MZWorld Library
Books Forum
By
Ayisha, at 9:05 PM
Hi Shankar,
Came across your site while browsing around…cool stuff u have going on here. Also I thought I’d tell u about something I came across, thought u might find it useful, bcoz ur in Technology…it’s this site called Myndnet…u should check it out..the link is here http://www.myndnet.com/login.jsp?referral=alpa83&channel=al453
It’s this cool place where u get paid for responding to queries…very cool stuff!! http://www.myndnet.com/login.jsp?referral=alpa83&channel=al453
Sign up n lemme know what u think…my mail id is barot.alpa@gmail.com
Cheers
Alpa
By
alpa, at 2:57 AM
bad car credit loan refinancing
bad credit auto refinancing
bad credit car refinancing
bad credit home refinancing
bad credit mortgage refinancing
bad credit refinancing
bad credit refinancing home loan
credit mortgage poor refinancing
poor credit refinancing
refinancing home with poor credit
bad credit mortgage refinancing
By
Anonymous, at 5:46 PM
mortgage refinancing
refinance
home mortgage refinance
refinance loan
auto refinance
refinance mortgage loan
bad credit refinance
refinance rate
home mortgage refinance loan
refinance mortgage rate
california refinance
bad credit mortgage refinance
texas mortgage refinance
refinance second mortgage
florida refinance mortgage
mortgage refinance california
home refinance rate
refinance mortgage interest rate
in refinance
florida refinance
refinance home mortgage rate
business refinance
home loan mortgage refinance loan
auto loan refinance
interest only refinance
refinance interest rate
no closing cost refinance
michigan mortgage refinance
lowest refinance rate
california mortgage refinance loan
refinance house
florida home refinance
refinance home mortgage interest rate
refinance student loan
california refinance home mortgage
bad credit refinance loan
refinance home mortgage home equity loan
refinance san diego
va refinance
refinance 2nd mortgage
mortgage refinance online
refinance comparison
va loan refinance
best refinance mortgage rate
california refinance loan
low refinance rate
poor credit refinance
florida refinance mortgage rate
debt consolidation refinance
cash out refinance
refinance loan rate
home equity mortgage refinance loan
ohio mortgage refinance
refinance after bankruptcy
best refinance mortgage
california mortgage rate refinance
home refinance bad credit
life refinance suv
refinance bankruptcy
houston refinance
mortgage loan refinance florida
california home loan refinance
refinance home equity
bad credit home loan refinance
refinance mortgage new jersey
mortgage refinance lowest rate
refinance mobile home
no credit refinance small business loan
refinance mortgage application
refinance jacksonville
current mortgage refinance rate
miami refinance
mortgage refinance calculator
loan mortgage rate refinance
va home loan refinance
michigan refinance
no cost refinance
mortgage refinance company
mortgage loan refinance and debt consolidation
auto lease refinance
home refinance california
refinance mortgage quote
refinance quote
refinance orlando
small business refinance
refinance company
michigan refinance mortgage loan
norfolk refinance
foreclosure refinance
refinance lender
new york refinance
home loan refinance rate
refinance honolulu
best refinance
business debt refinance
countrywide home loan refinance
refinance dallas
best refinance rate
free quote on refinance
mortgage refinance information
By
Anonymous, at 7:19 AM
mortgage refinancing
refinance
home mortgage refinance
refinance loan
auto refinance
refinance mortgage loan
bad credit refinance
refinance rate
home mortgage refinance loan
refinance mortgage rate
california refinance
bad credit mortgage refinance
texas mortgage refinance
refinance second mortgage
florida refinance mortgage
mortgage refinance california
home refinance rate
refinance mortgage interest rate
in refinance
florida refinance
refinance home mortgage rate
business refinance
home loan mortgage refinance loan
auto loan refinance
interest only refinance
refinance interest rate
no closing cost refinance
michigan mortgage refinance
lowest refinance rate
california mortgage refinance loan
refinance house
florida home refinance
refinance home mortgage interest rate
refinance student loan
california refinance home mortgage
bad credit refinance loan
refinance home mortgage home equity loan
refinance san diego
va refinance
refinance 2nd mortgage
mortgage refinance online
refinance comparison
va loan refinance
best refinance mortgage rate
california refinance loan
low refinance rate
poor credit refinance
florida refinance mortgage rate
debt consolidation refinance
cash out refinance
refinance loan rate
home equity mortgage refinance loan
ohio mortgage refinance
refinance after bankruptcy
best refinance mortgage
california mortgage rate refinance
home refinance bad credit
life refinance suv
refinance bankruptcy
houston refinance
mortgage loan refinance florida
california home loan refinance
refinance home equity
bad credit home loan refinance
refinance mortgage new jersey
mortgage refinance lowest rate
refinance mobile home
no credit refinance small business loan
refinance mortgage application
refinance jacksonville
current mortgage refinance rate
miami refinance
mortgage refinance calculator
loan mortgage rate refinance
va home loan refinance
michigan refinance
no cost refinance
mortgage refinance company
mortgage loan refinance and debt consolidation
auto lease refinance
home refinance california
refinance mortgage quote
refinance quote
refinance orlando
small business refinance
refinance company
michigan refinance mortgage loan
norfolk refinance
foreclosure refinance
refinance lender
new york refinance
home loan refinance rate
refinance honolulu
best refinance
business debt refinance
countrywide home loan refinance
refinance dallas
best refinance rate
free quote on refinance
mortgage refinance information
By
Anonymous, at 7:20 AM
Hey, while searching for widgets for my blog, I stumbled upon www.widgetmate.com and wow! I found what I wanted. A cool news widget. My blog is now showing latest news with title, description and images. Took just few minutes to add. Awesome!
By
Anonymous, at 12:35 AM
add to cart Gelonida Pfizer
Relpax pharmacy
drugs Maxalt pharmacy
Zomig pharmacy
drugs Omeprazol pharmacy
Xatral pharmacy
Citalopram xanax ratiopharm
Risperdal xanax tafil
Telfast pharmacy
drugs Sirdalud
Regenon
drugs Zaldiarpharmacy
Glucobay pharmacy
add to cart Gelonida pharmacy
By
Anonymous, at 5:41 AM
http://www.nofelet.biz/
Home
viagra cialis levitra
compare viagra cialis levitra
levitra link
all about levitra
levitra levitra
what is levitra
compare cialis levitra viagra
levitra or viagra
levitra milf
levitra compare viagra
effects levitra side
side effects of levitra
order levitra
generic viagra cialis levitra buy cheap
index2.php
Home
cialis compare levitra viagra
cialis comparison levitra viagra
cialis levitra viagra vs vs
cialis levitra viagra vs
cialis levitra sales viagra
cialis generic levitra viagra
cialis dysfunction erectile levitra viagra
cialis drug levitra viagra
cialis levitra search viagra vs
which is better viagra cialis or levitra
cialis levitra naion viagra
cialis levitra search viagra vs vs
cialis levitra phentermine tramadol viagra xanax
cialis cialis levitra levitra search viagra viagra vs vs
discount cialis levitra viagra
am.info am.info levitra levitra link site
com levitra link net site site vi.blogspot.com
com levitra link msnlevitra.blogspot.com site
en.wikipedia.org levitra link wiki
about.wspace com levitra link net service.de site site
buy buy cheap.blogspot.com cheap.blogspot.com levitra levitra link site
buy image levitra levitra.html link psc.wa.edu.au
000005e4.htm buy id levitra link mess okon reqdis students.westport.k12.ct.us
buy levitra link online1stokcom
buy levitra link onlinemusicbox1com
buy levitra link onlinee pharmacycom top
buy levitra link onlinepenu
com levitra link msnlevitra.blogspot.com net site site
add levitra link
levitra link orerboght120hostnet
levitra link sherbesttidefanscom
derevantmicroircom levitra link
levitra link portadynunet
levitra link varololikeepkidshealthycom
levitra link rovanagreekbostoncom
buy levitra link onlineinttc
buy levitra link onlineplaysitede
levitra
buy levitra
cialis levitra
buy levitra online
cheap levitra
generic levitra
levitra side effects
levitra online
buy buy buy buy buy buy cialis cialis.jugem.jp href href href levitra levitrarx.jugem.jp viagra viagra.jugem.jp
cialis levitra vs
order levitra online
viagra levitra
levitra online pharmacy
levitra vs viagra
levitra prescription
levitra price
levitra site sys.kcn.ru
levitra dosage
cyalis levitra sales viagra
bayer levitra
commentview,guid inurl levitra
levitra on line
generic levitra say wordpress
drug for impotence levitra
levitra pill
levitra sample
buy levitra online viagra
allmeds.szm.com allmeds.szm.com buy buy buy href href index.html levitra levitra levitra levitra levitra online online.html
dysfunction erectile levitra
levitra sale
buy buy buy href href index.html levitra levitra levitra levitra levitra online online.html rxpharm.szm.com rxpharm.szm.com
cost levitra
cialis compare levitra
levitra woman
levitra information
levitra now online
low cost levitra
discount levitra
levitra review
buy cheap levitra
buy cheap levitra online
levitra canada
levitra 20mg
levitra free sample
levitra 10mg
levitra vardenafil
best price for levitra
alcohol levitra
buy levitra line
drug levitra
buy entry html levitra mt tb this trackback trackback url
cialis comparison levitra
levitra result
levitra vardenafil hcl
compare levitra viagra
image levitra optional post.html ticket url
purchase levitra
comparison levitra viagra
levitra commercial
levitra info
levitra pharmacy
levitra cheapest
dosage levitra medication
gente.chueca.com gente.chueca.com href href index.html levitra levitra levitra levitra levitra online online.html rxviagra rxviagra
generic levitra vardenafil
buy generic levitra
levitra story
effects levitra medication side
coupon levitra
buy levitra viagra
levitra overdose
levitra versus viagra
buy buy buy buy gente.chueca.com gente.chueca.com href href levitra levitra levitra levitra levitra levitra.html online online.html rxviagra rxviagra
levitra uk
where to buy levitra
levitra medication
buy cheap.blogspot.com levitra
cheap generic levitra
purchase levitra online
levitra alternative
cheap cheap generic generic gente.chueca.com gente.chueca.com href href levitra levitra levitra levitra levitra.html levitra.html rxviagra rxviagra
225mess buy id levitra mcturl.com r
free levitra
levitra testimonials
drug levitra online purchase
levitra tablet
cheap levitra online
levitra 20 mg
cialis levitra viagra
levitra order
levitra online order
levitra viagra
levitra viagra vs
dosage levitra
levitra line
drug impotence levitra
information levitra
cost levitra low
canada levitra
20mg levitra
free levitra sample
10mg levitra
best levitra price
hcl levitra vardenafil
levitra purchase
commercial levitra
info levitra
cheapest levitra
buy levitra where
levitra online purchase
alternative levitra
20 levitra mg
better cialis levitra viagra which
buy buy levitra levitra online online viagra viagra
health levitra sexual viagra
compared levitra viagra
alternative buy lavitra levitra viagra
buy levitra levitra online viagra
cialis discount levitra viagra
blog levitra order trackback url
order cheap levitra
what is relpax
relpax relpax
all about relpax
relpax link
relpax buy
relpax milf
relpax compare
relpax cheap
generic relpax
relpax effects
relpax online
By
Anonymous, at 6:07 AM
In 1998 a particular blue pill came as an angel that rescued all those tormented by the demon of erectile dysfunction. That blue pill was christened Viagra. Since then viagra has completely changed the scene of the treatment of ED. Nowadays one can even buy viagra online. Customers are reluctant to buy viagra from the local chemists for a varied number of reasons since the availability of viagra online. In order to lure the customers the online pharmacies also offer cheap viagra.
By
viagra, at 10:15 PM
This post on .Net remoting is a direct copy from Mike Gunderloy's Book MCAD/MCSD Developing XML Web Services and Server Components (Exam 70-310) Chapter 4 and as such you should have given an acknowledgment, otherwise your giving the impression that it's you own work and misleading readers.
By
Anonymous, at 4:59 PM
buy cheap tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
buy cheap cialis viagra levitra paxil tramadol
spain viagra online
Xanax Buy Xanax Buy Cheap Xanax Online Xanax Order
Phentermine Buy Phentermine Online Phentermine Cheap Phentermine Prescription Phentermine Order
Valium Buy Valium Online Valium Cheap Valium Pharmacy Valium Order
Cialis Buy Cialis Online Buy Cialis Cheap Cialis Order
Viagra Buy Viagra Cheap Viagra UK Us Viagra In Span Viagra Cheap Pills Viagra Order
Tramadol Buy Tramadol Online Tramadol Cheap Tramadol Overnight Tramadol Order Tramadol
Tramadol Buy Tramadol Online Cheap Tramadol
By
tramadol, at 7:08 PM
The key is to use something that may be new to you: control adapters. These are little chunks of logic that you add to your web site to effectively "adapt" an Malayalam search engineASP.NET control to render the HTML you prefer. The ASP.NET 2.0 CSS Friendly Control Adapters kit
By
Anonymous, at 4:49 AM
Bad credit? No credit? Other financial problems? I allways use be this site payday loan faxless. Cash is deposited directly to your account, no documents to fax, fast & easy approval - No long forms.
By
Anonymous, at 6:34 AM
Have a financial emergency? Need fast cash in a hurry? Looking for the best payday loan service online? I allways use by this site bad credit payday loan. You need only personal identification, a checking account, and an income from a job or government benefits.
By
Anonymous, at 11:51 AM
black mold exposureblack mold symptoms of exposurewrought iron garden gatesiron garden gates find them herefine thin hair hairstylessearch hair styles for fine thin hairnight vision binocularsbuy night vision binocularslipitor reactionslipitor allergic reactionsluxury beach resort in the philippines
afordable beach resorts in the philippineshomeopathy for eczema.baby eczema.save big with great mineral makeup bargainsmineral makeup wholesalersprodam iphone Apple prodam iphone prahacect iphone manualmanual for P 168 iphonefero 52 binocularsnight vision Fero 52 binocularsThe best night vision binoculars here
night vision binoculars bargainsfree photo albums computer programsfree software to make photo albumsfree tax formsprintable tax forms for free craftmatic air bedcraftmatic air bed adjustable info hereboyd air bedboyd night air bed lowest pricefind air beds in wisconsinbest air beds in wisconsincloud air beds
best cloud inflatable air bedssealy air beds portableportables air bedsrv luggage racksaluminum made rv luggage racksair bed raisedbest form raised air bedsaircraft support equipmentsbest support equipments for aircraftsbed air informercialsbest informercials bed airmattress sized air beds
bestair bed mattress antique doorknobsantique doorknob identification tipsdvd player troubleshootingtroubleshooting with the dvd playerflat panel television lcd vs plasmaflat panel lcd television versus plasma pic the bestThe causes of economic recessionwhat are the causes of economic recessionadjustable bed air foam The best bed air foam
hoof prints antique equestrian printsantique hoof prints equestrian printsBuy air bedadjustablebuy the best adjustable air bedsair beds canadian storesCanadian stores for air beds
By
hoof prints, at 5:20 AM
Cialis have been found to have impressive effects on the people with depression but only on when it is had on depression. Cialis is first an erectile dysfunction drug and any positive effects that it shows on depression are purely coincidental. Cialis should never be had as a depression drug. http://www.buy-cialis-online-now.com
By
Robin Calrk, at 3:23 AM
Levitra is another prescription impotence treatment. Levitra comes as an orange pill in four dosage forms of 2.5mg, 5mg, 10mg, and 20mg respectively. It affects the working of PDE5 enzyme, preserves cGMP levels, and aids erection strength and durability. Few men find Viagra does not work for them, and so they go for Levitra. This drug is found to be safe because it comes in low dosage strengths. http://www.levitrabliss.com/
By
McCutcheon, at 10:25 PM
Anxiety disorder is considered to be one of the worst mental conditions that affect human beings by making them prone to baseless and groundless worries but with the arrival of anti-anxiety medications like xanax in the pharmaceutical market, successful treatment of anxiety related disorders has become an instant possibility. But, instead of straightway moving ahead to use Xanax and other medicines to treat anxiety such as Buspar and Tenormin, you can log in to http://www.pill-care.com and get hold of fundamental tidbits on these medicines first.
By
xanax, at 2:25 AM
The drug war between the anti-impotency medicines such as Viagra, Cialis and Levitra is continuously on the rise but instead of preferring the other two erectile dysfunction drugs Cialis and Levitra, impotency afflicted men are opting for viagra only, the Pfizer manufactured drug to treat erectile dysfunction. This is because Viagra if the first erectile dysfunction medication to provide men successful relief from impotency and to known more about tidbits on Viagra, please visit the website http://www.viagraforce.com
By
viagra, at 2:49 AM
Cardiovascular side effects are often associated with erectile dysfunction drug, but in the case of Generic Cialis, early clinical tests prove that this drug does not affect blood pressure in the same way as other similar drugs do. Side effects are more likely to be experienced if you are over sixty-five. http://www.buy-cialis-online-now.com
By
Katherine, at 4:43 AM
Wow It really seems like mister here did his homework! Great effort in constructing this information, I really got a new sense of what's going on. Well, at least we can call it an update to what I already knew. But it's good to have yourself really looking into this stuff and putting it out there. I probably would have not investigated this material in wow g-d knows how long. I can really say I picked up some knowledge from this piece and you can most definitely count me referring some readers to your page, thanks! Really enjoyed and it was my pleasure to read on!
By
generic levitra, at 5:07 PM
Erectile Dysfunction - ED Erectile dysfunction (ED) is the inability of a man to achieve or maintain an erection
sufficient for his or his partner's sexual needs. Most men experience this at some point in their lives, usually
by age 40. Incidence of the disorder generally increases with age. ED affects about 5% of men in their 40s and
15-25% of men by the age of 65. 50% of men over the age of 40 may experience transient ED and inadequate erection.
Some perfect resources for ed medicine. Top Ed medicine Viagra and Levitraand the most powerfull medicine Cialis
By
Joe, at 12:04 AM
Post a Comment
<< Home