COM+ Web 服務:通過複選框路由到 XML Web Services(2) (微軟中國)

來源:互聯網
上載者:User
services|web|xml|複選框|微軟 事務性組件樣本
簡單的計算機遠算不上工作量繁重的商務應用程式,因此我們現在考慮帶有對象池的適於 COM+ 事務性組件的應用程式。
最容易管理和配置的組件是由 ServicedComponent 匯出的Managed 程式碼組件,如以下 C# 樣本所示:
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=25)]  [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 WHERE 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;      }}

要建立並運行此 C# 組件,在完成編輯串連值以串連到 Microsoft SQL Server™ 資料庫之後,需要使用 sn.exe 產生 sctrans.snk 加強式名稱關鍵字檔案,然後在 using 語句中使用程式集引用對其進行編譯。如果您在伺服器上進行部署,應使用 gacutil.exe(如果正在使用 SDK)或通過 .NET 架構使用者介面將程式集放入 GAC,然後運行 regsvcs.exe,註冊 COM+ 託管組件。Regsvcs.exe 將使用以下屬性,將組件發布為伺服器上的 SOAP 端點和伺服器(進程外)啟用:
[assembly: ApplicationActivation(ActivationOption.Server,    SoapVRoot="CSSoapSQL")]

此組件在每種方法調用中使用不同的事務,具有一個自動完成方法,並被配置為進行緩衝。使用託管和非託管 COM+ 組件時,對象池和事務將如所預期的那樣通過 SOAP 運行。例如,如果使用下列 VBScript 通過 SOAP 訪問以下 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 10  WScript.Echo i & " " & j & " " & c.CountUp("SCWKONC")  nextnext

將顯示以下輸出內容:
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-74be-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 10 NC af26b53b-4a1f-48c8-8880-518c2b55a7ce 1 9 494 NC 6e41f32f-74be-45f0-94c0-989e7e1c5672 1 10 495 NC 6e41f32f-74be-45f0-94c0-989e7e1c5672 2 1 13 NC af26b53b-4a1f-48c8-8880-518c2b55a7ce 2 2 14 NC af26b53b-4a1f-48c8-8880-518c2b55a7ce 2 3 15 NC af26b53b-4a1f-48c8-8880-518c2b55a7ce 2 4 499 NC 6e41f32f-74be-45f0-94c0-989e7e1c5672 2 5 17 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 19 NC af26b53b-4a1f-48c8-8880-518c2b55a7ce 2 9 20 NC af26b53b-4a1f-48c8-8880-518c2b55a7ce 2 10 21 NC af26b53b-4a1f-48c8-8880-518c2b55a7ce 

這就是所預期的緩衝的組件:從緩衝池中拖出對象並重新使用。使用用戶端啟用的緩衝組件的行為都是相同的。
非託管組件的對象池和事務也如所預期的那樣運行(雖然 Visual Basic 6.0 組件不支援對象池)。需要為大多數非託管應用程式通過 COM+ 管理工具設定緩衝和事務屬性。

傳遞引用


WKO 與 CAO 模型的一個關鍵區別在於它們向有狀態的對象傳遞引用的能力。以下是 C# ServicedComponent 樣本,顯示了此操作的基本步驟:
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)    {      _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; }  }}

此 C# 程式有兩個類: ChildParent。如果運行以下 VBScript 樣本,WKO 與 CAO 模型的區別會更加明顯:
set c1 = GetObject   ("soap:wsdl=http://jnoss4/refpass/RefPass.Child.soap?wsdl")set c2 = GetObject   ("soap:wsdl=http://jnoss4/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()

運行時將顯示以下輸出內容:
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

名稱和值說明了單一調用已知對象的無狀態性質,因為組件是使用不同的方法調用建立的,所以方法調用之間不保留名稱或值。
如果匯出用戶端代理,然後匯入到另一台用戶端電腦上,並且運行了下面的 VBScript,則 SOAP 啟用將是 CAO 而不是 WKO:
'直接建立兩個對象set c1=CreateObject("RefPass.Child")set c2=CreateObject("RefPass.Child")'設定第一個對象的名稱,並調用數次'以遞增對象內部計數器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()'建立父物件set p=CreateObject("RefPass.Parent")'將子物件傳遞到父物件,並從父物件調用子物件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)'現在調用儲存在父物件內部的子物件dim c9WScript.Echo p.CountUp(c9)'從父物件擷取該對象並直接調用Set c3 = p.GetRef()WScript.Echo c3.CountUp()

從命令列運行時,將顯示以下輸出內容:
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

即使在通過 SOAP 調用時,CAO 啟用也會保留狀態,並且允許通過 SOAP 來回傳遞對象引用。名稱和值都保留在伺服器上的類執行個體中,並且引用可以正確工作。這兩種指令碼都調用相同的編譯 C# 組件,只是 .NET Remoting 啟用模型不同。
除了使用 CreateObject 調用 CAO 啟用外,還可以使用帶有 COM+ 的Moniker,它可以提供 CAO 啟用來替代 WKO(類型名稱和程式集Moniker)。以下指令碼:
'直接建立兩個對象set c1=GetObject("soap:typename=RefPass.Child,assembly=RefPass")set c2=GetObject("soap:typename=RefPass.Child,assembly=RefPass")'設定第一個對象的名稱,並調用數次'以遞增對象內部計數器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()'建立父物件set p=GetObject("soap:typename=RefPass.Parent,assembly=RefPass")'將子物件傳遞到父物件,並從父物件調用子物件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)'現在調用儲存在父物件內部的子物件dim c9WScript.Echo p.CountUp(c9)'從父物件擷取該對象並直接調用Set c3 = p.GetRef()WScript.Echo c3.CountUp()

將顯示以下輸出內容:
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

這與上面的 VBScript CreateObject( ProgID ) 樣本的輸出內容相同。因為常規 COM+ 啟用路徑被 SOAP 代理應用程式截獲,所以可以使用 CoCreateInstanceCreateInstance 以及其他傳統的 COM+ 啟用方法來調用使用 COM+ Web 服務的用戶端啟用的對象。
程式集和類型名稱Moniker,對於從Managed 程式碼用戶端遠程擷取預先配置的用戶端啟用也很有用,如下例所示:
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

編譯並運行此 Visual Basic .NET 應用程式,將產生與前面兩個 VBScript CAO 樣本相同的輸出內容。
因為伺服器應用程式將組件發布為 CAO 和 WKO 兩種形式,所以由遠程用戶端選擇啟用方法。雖然可能只對學術研究有意義,但是單一用戶端電腦確實可以使用同一組件的兩種遠程啟用方法,訪問遠程伺服器上同一個 SOAP 發布的虛擬根。

相關文章

E-Commerce Solutions

Leverage the same tools powering the Alibaba Ecosystem

Learn more >

Apsara Conference 2019

The Rise of Data Intelligence, September 25th - 27th, Hangzhou, China

Learn more >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。