services|web|xml| check box | microsoft
Transactional Components Sample
The simple calculator is far from being a heavy workload business application, so we now consider applications with object pooling that are suitable for COM + transactional components.
The easiest components to manage and configure are the
ServicedComponentExported managed code components, as shown in the following C # example:
Using system;using system.reflection;using system.runtime.interopservices;using system.enterpriseservices;using System.data;using System.Data.SqlClient; [Assembly:applicationname ("Sctrans")] [Assembly:applicationactivation (activationoption.server, soapvroot= "SCTrans")] [Assembly:assemblykeyfile ("Sctrans.snk")]namespace Sctrans{ public interface isctrans { string Countup (string Key); } [objectpooling (Minpoolsize=0, MaxPoolSize= ] [justintimeactivation (True)] [classinterface (classinterfacetype.autodual)] [transactionattribute (transactionoption.requiresnew)] public class SCTransSQLNC: ServicedComponent, isctrans { [autocomplete] public string CountUp ( String Key) { _command = new SqlCommand ("", _connection); _command.commandtype= Commandtype.text; _command. Connection.Open (); _command. CommandText = "UPDATE callcount with (rowlock) Set callcount = CallCount + 1 WHE RE machine= ' "+ Key +" ' "; _command. ExecuteNonQuery (); _command. Connection.close (); _numcalls++; return (_numcalls + " NC "+ _guid); } protected override bool CanBePooled () { return true; } private int _numcalls = 0; private string _guid = Guid.NewGuid (). ToString (); private SqlConnection _connection = new SqlConnection ("User id= myuser;password=my! Password; database=soaptest;server=myserver "); private SqlCommand _coMMAND;     &NBSP}}
To establish and run this C # component, after you finish editing the connection value to connect to the Microsoft SQL Server™ database, you need to use Sn.exe to build the sctrans.snk enhanced name keyword file, and then
usingStatement to compile it using an assembly reference. If you are deploying on a server, use Gacutil.exe (if you are using the SDK) or put the assembly in the GAC through the. NET Framework user interface, and then run Regsvcs.exe to register the COM + managed component. Regsvcs.exe uses the following properties to publish the component as a SOAP endpoint and server (out-of-process) activation on the server:
[Assembly:applicationactivation (Activationoption.server, soapvroot= "Cssoapsql")]
This component uses a different transaction in each method invocation, has an automatic completion method, and is configured to buffer. When using managed and unmanaged COM + components, object pooling and transactions will run through SOAP as expected. For example, if you use the following VBScript through SOAP to access the following
ServicedComponent:
Mon = "Soap:wsdl=http://jnoss3/sctrans/sctrans.sctranssqlnc.soap?" WSDL "WScript.Echo (Mon) For i = 1 to 2 set c = GetObject (Mon) for j = 1 to ten WScript.Echo I &" "& J &" "&A mp C.countup ("Scwkonc") nextnext
The following output is displayed:
C:\moniker>actscwkomicrosoft (R) Windows Script Host Version 5.6Copyright (C) Microsoft Corporation 1996-2001. All rights Reserved.soap:wsdl=http://jnoss3/sctrans/sctrans.sctranssqlnc.soap? WSDL1 1 486 NC 6e41f32f-74be-45f0-94c0-989e7e1c5672 1 2 487 NC 6e41f32f-74be-45f0-94c0-989e7e1c5672 1 3 488 NC 6e41f32f-74 be-45f0-94c0-989e7e1c5672 1 4 489 NC 6e41f32f-74be-45f0-94c0-989e7e1c5672 1 5 490 NC 6e41f32f-74be-45f0-94c0-989e7e1c5672 1 6 8 NC af26b53b-4a1f-48c8-8880-518c2b55a7ce 1 7 9 NC AF26B53B-4A1F-48C8-8880-518C2B55A7CE 1 8 NC af26b53b-4a1f-48c8-8880-518c2b55a7ce 1 9 494 NC 6e41f32f-74be-45f0-94c0-989e7e1c5672 1 495 NC 6e41f32f-74be-45f0-94c0-989e7e1c5672 2 1 NC AF26B53B-4A1F-48C8-8880-518C2B55A7CE 2 2 NC af26b53b-4a1f-48c8-8880-518c2b55a7ce 2 3 NC AF26B53B-4A1F-48C8-8880-518C2B55A7CE 2 4 499 NC 6e41f32f-74be-45f0-94c0-989e7e1c5672 2 5 NC AF26B53B-4A1F-48C8-8880-518C2B55A7CE 2 6 501 NC 6e41f32f-74be-45f0-94c0-989e7e1c5672 2 7 502 NC 6e41f32f-74be-45f0-94c0-989e7e1c5672 2 8 NC af26b53b-4a1f-48c8-8880-518c2b55a7ce 2 9 NC af26b53b-4a1f-48c8-8880-518c2b55a7ce 2 Ten NC Af26b53b-4a1f-48c8-8880-518c2b55a7ce
This is the expected buffer component: Drag the object from the buffer pool and reuse it. The behavior of using a client-activated buffering component is the same.
The object pools and transactions of unmanaged components also run as expected (although the Visual Basic 6.0 component does not support object pooling). You need to set buffering and transaction properties for most unmanaged applications through the COM + Administration tool.
Passing references
A key difference between Wko and CAO models is their ability to pass references to stateful objects. The following is C #
ServicedComponentExample, shows the basic steps for this operation:
Using system;using system.reflection;using system.enterpriseservices;using System.Runtime.InteropServices; [Assembly:applicationname ("Refpass")] [Assembly:applicationactivation (activationoption.server, soapvroot= "RefPass")] [Assembly:assemblykeyfile ("Refpass.snk")]namespace Refpass{ public interface iparent { string Setref (object inkid); object GetRef (); string Countup (Object obj); } public interface ichild { string GetValue (); string countup (); void SetName ( String key); } [classinterface (classinterfacetype.autodual)] public class Parent : ServicedComponent, iparent { protected child _kid = null; public string Setref (object Inkid) { &Nbsp; _kid = (Child) Inkid; return _kid. GetValue (); } public object GetRef () { return (object) _kid; } public String Countup (Object obj) { child kid = (child) obj; if (kid = = null) return _kid. Countup (); else return kid. Countup (); }} [classinterface (Classinterfacetype.autodual)] public class child:servicedcomponent, ichild { private int _counter = 0; private string _name = "None"; public string Countup () {_counter++; return GetValue (); } public string GetValue () {return (_name + "" +_counter. ToString ()); } public void SetName (string key) {_name = key;}  &NBSP}}
This C # program has two classes:
ChildAnd
Parent。 If you run the following VBScript example, the difference between the Wko and the CAO model is more pronounced:
Set C1 = GetObject ("soap:wsdl=http://jnoss4/refpass/refpass.child.soap?wsdl") Set C2 = GetObject ("Soap:wsdl=http://jn OSS4/REFPASS/REFPASS.CHILD.SOAP?WSDL ") C1. SetName ("C1") WScript.Echo C1. Countup () WScript.Echo C1. Countup () WScript.Echo C1. Countup () WScript.Echo C1. Countup () WScript.Echo C1. Countup () C2. SetName ("C2") WScript.Echo C2. Countup () WScript.Echo C2. Countup () WScript.Echo C2. Countup () WScript.Echo C2. Countup () WScript.Echo C2. Countup ()
The following output is displayed at run time:
C:\moniker>refpasswkomicrosoft (R) Windows Script Host Version 5.6Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.none 1none 1none 1none 1none 1none 1none 1none 1none 1none 1
The name and value describe the stateless nature of a single call to a known object, because the component is created with a different method invocation, so the name or value is not preserved between the method calls.
If you export a client agent and then import it to another client computer and run the following VBScript, SOAP activation will be CAO instead of Wko:
' Directly create two object set C1=createobject (' Refpass.child ') set C2=createobject ("Refpass.child") ' Sets the name of the first object and calls several times ' to increment the object's internal counter c1. SetName ("C1") WScript.Echo C1. Countup () WScript.Echo C1. Countup () WScript.Echo C1. Countup () WScript.Echo C1. Countup () WScript.Echo C1. Countup () ' Sets the name of the first object and calls several times ' to increment the object's internal counter c2. SetName ("C2") WScript.Echo C2. Countup () WScript.Echo C2. Countup () WScript.Echo C2. Countup () WScript.Echo C2. Countup () WScript.Echo C2. Countup () ' Creates the parent object set P=createobject ("Refpass.parent") "passes the child object to the parent object and invokes the child object from the parent object WScript.Echo P.setref (C1) WScript.Echo p. Countup (C2) WScript.Echo P.countup (C2) WScript.Echo P.countup (C2) WScript.Echo P.countup (C2) ' Now calls the child objects stored inside the parent object Dim C9wscript.echo P.countup (C9) ' Gets the object from the parent object and calls the set C3 directly = P.getref () WScript.Echo C3. Countup ()
When run from the command line, the following output is displayed:
C:\moniker>refpassclmicrosoft (R) Windows Script Host Version 5.6Copyright (C) Microsoft Corporation 1996-2001. All rights reserved. C1 1C1 2C1 3C1 4C1 5C2 1C2 2C2 3C2 4C2 5C1 5C2 6C2 7C2 8C2 9C1 6C1 7
CAO activation retains state even when invoked through SOAP, and allows object references to be passed back and forth through soap. Both the name and the value remain in the class instance on the server, and the reference works correctly. Both scripts invoke the same compiled C # component, except that the. NET Remoting activation model is different.
In addition to using
CreateObjectInvoking Cao Activation, you can also use a name object with COM + that provides CAO activation instead of Wko (type name and assembly moniker). The following script:
' Create two objects directly set C1=getobject ("Soap:typename=refpass.child,assembly=refpass") Set C2=getobject ("Soap:typename= Refpass.child,assembly=refpass ") ' Sets the name of the first object and calls several times ' to increment the object's internal counter c1. SetName ("C1") WScript.Echo C1. Countup () WScript.Echo C1. Countup () WScript.Echo C1. Countup () WScript.Echo C1. Countup () WScript.Echo C1. Countup () ' Sets the name of the second object and calls several times ' to increment the object's internal counter c2. SetName ("C2") WScript.Echo C2. Countup () WScript.Echo C2. Countup () WScript.Echo C2. Countup () WScript.Echo C2. Countup () WScript.Echo C2. Countup () ' Creates the parent object Set P=getobject (' Soap:typename=refpass.parent,assembly=refpass ') ' to pass the child object to the parent object, and invokes the child object from the parent object WScript.Echo P.setref (C1) WScript.Echo P.countup (C2) WScript.Echo P.countup (C2) WScript.Echo P.countup (C2) WScript.Echo P.countup (C2) ' Now calls the child objects stored inside the parent object Dim C9wscript.echo P.countup (C9) ' Get the object from the parent object and call set C3 = P.getref directly () WScript.Echo C3. Countup ()
The following output is displayed:
C:\moniker>refpasscamicrosoft (R) Windows Script Host Version 5.6Copyright (C) Microsoft Corporation 1996-2001. All rights reserved. C1 1C1 2C1 3C1 4C1 5C2 1C2 2C2 3C2 4C2 5C1 5C2 6C2 7C2 8C2 9C1 6C1 7
This is with the VBScript above
CreateObject (
ProgID
)The output of the sample is the same. Because the general COM + activation path is intercepted by the SOAP proxy application, you can use the
CoCreateInstance、
CreateInstanceand other traditional COM + activation methods to invoke client-activated objects that use COM + Web services.
assembly and type name objects are also useful for remotely obtaining preconfigured client activation from managed code clients, as shown in the following example:
Imports systemimports System.Runtime.InteropServicesModule refpassclsub Main () dim Childmoniker = "Soap:assembly=refpass,typename=refpass.child" dim ParentMoniker = "Soap: Assembly=refpass,typename=refpass.parent " dim c1,c2,p as Object c1 = Marshal.bindtomoniker (Childmoniker) console.writeline (C1. SetName ("C1")) console.writeline (C1. Countup ()) console.writeline (C1. Countup ()) console.writeline (C1. Countup ()) console.writeline (C1. Countup ()) console.writeline (C1. Countup ()) c2 = Marshal.bindtomoniker (childmoniker) Console.WriteLine (C2. SetName ("C2")) console.writeline (C2. Countup ()) console.writeline (C2. Countup ()) console.writeline (C2. Countup ()) console.writeline (C2. Countup ()) console.writeline (C2. Countup ()) p = Marshal.bindtomoniker (parentmoniker) Console.WriteLine (P.setref (C1)) console.writeline (P.countup (C2)) console.writeline (P.countup (C2)) console.writeline (P.countup (C2)) console.writeline (P.countup (C2)) dim c9 Console.WriteLine (P.countup (C9)) dim C3 = P.getref () Console.WriteLine (C3. Countup ()) End SubEnd Module
Compiling and running this Visual Basic. NET application produces the same output as the previous two VBScript samples.
Because the server application publishes components as CAO and Wko two forms, the remote client chooses the activation method. Although it may only make sense for academic research, a single client computer can indeed use two remote activation methods of the same component to access the virtual root of the same SOAP publication on a remote server.