大概看了一下書,照做了一下,感覺功能上主要就是能實現一個事務的功能,其他的沒有看到什麼新鮮的東東。還有就是這個也能實現remoting那種功能, 可以計算機間通信,不過書裡講的也不深,自己又懶得找資料看了,大概也就是明白了一個基本的實現和使用吧。對com+組件的設置可以在程序裡用屬性設置, 也可以在com+組件服務浏覽器裡進行設置。下面是有組件和無組件的代碼
有組件:
using System;
using System.Collections.Generic;
using System.Text;
using System.EnterpriseServices;
using System.IO;
using MySql.Da
ta.MySqlClient;
using MySql.Da
ta;
//在這裡進行的配置,都可以在管理工具中的組件服務中進行相應的配置,服務組件使用regsvcs dllname.dll的方式來部署
//要調用這種有組件的服務,調用程序需要引用System.EnterpriseServices和這個組件的dll
[assembly:ApplicationName("EnterpriseServiceTest")]//在componentservice浏覽器中顯示的應用程序的名字
[assembly:Description("An EnterpriseService Test")]//關於這個程序的描述文本,將顯示在componentservice浏覽器中的com+應用程序屬性中
//指定此程序是運行在客戶機(調用方)的進程中(ActivationOption.Library)還是運行在一個單獨的進程中(ActivationOption.Server)
//如果使用ActivationOption.Library則在使用componetservice浏覽器創建安裝包的時候,就不能使用application proxy選項
//這個選項也可以在注冊後,在組件服務中設置和修改。如果使用ActivationOption.Server,則可以在組件服務中導出時,生成代理MSI安裝文件,然後在客戶機中
//執行對代理的安裝,並在客戶機上的客戶端應用程序引用安裝的DLL文件,實現類似remoting效果的遠程通信,也可以只生成類庫的msi安裝文件,直接在其他計算機中
//安裝,並在客戶應用程序中引用安裝的DLL即可直接在本機使用組件的功能
[assembly:ApplicationActivation(ActivationOption.Library)]
[assembly:ApplicationAccessControl(false)]//定義程序的安全配置,bool值表示是否啟用訪問控制
namespace EnterpriseServiceTest
{
public interface IEnterpriseServiceTest
{
string ProceedStr(string str);
}
[EventTrackingEnabled(true)]//標志是否能用componentservice浏覽器來監視這個對像,默認是false,因為允許監視會降底程序性能
[Description("A TestComponet")]//浏覽器中組件屬性中顯示的描述文本
//如果指定了 JIT 激活,則不能在 COM+ 目錄中禁用該激活功能,反之亦然。如果在 COM+ 目錄中啟用了該激活功能,則必須在組件中指定該功能。
//對於在 COM+ 中配置的組件,JIT 激活默認為關閉;但如果請求自動事務,則自動啟用 JIT 激活。
//使用類在實例化的時候不激活,而是在調用第一個方法時激活
[JustInTimeActivation(false)]
[ObjectPooling(1,10)]//如果組件初始化需要時間較長,則可以用此屬性配置對像池,設置對像池的最小和最大對像數
//Required如果已經運行在一個事務中就使用當前的事務,如果沒有事務,則創建一個新的
//RequiresNew不管是否已經運行在一個事務中,都創建一個新的事務,並運行於其中
//Supported如果運行在一個事務中就使用當前的事務,如果沒有事務,則不會創建新事務
//NotSupported即使存在一個事務,也不會運行在這個事務當中
//Disabled忽略當前環境中的任何事物處理
[Transaction(TransactionOption.Required)]
//ConstructionEnabled第二個參數的值會顯示在componentservice浏覽器中的Activation設置中,先可以通過那裡來修改這個值,最終這個值可以通過
//ServicedComponent類中的Construct方法得到
[ConstructionEnabled(true, Default = "Database=Test;Da
ta Source=192.168.1.3;Port=3306;User Id=root;Password=1980425")]
//ServicedComponent是所有服務組件類的基類,為激活和構造提供了一些方法。
//啟動了使用繼承了ServiceComponet類的類的程序,都會自動啟動配置com+應用程序,但啟動程序必須有相應的權限才能進行配置。
//手式配置則使用.net提供的regsvcs assemblyname(xxx.dll),配置好後可以在管理工具中的組件服務中com+應用程序中來驗證配置是否成功
//此程序集的生成要使用強名稱來升成,否則在進行上面的安裝配置的時候會失敗,另外.net的類庫創建的時候默認的是ComVisible是false
//要在AssemblyInfo.cs文件中,將這個屬性更改成true才可以成功安裝
public class TestComponent:ServicedComponent,IEnterpriseServiceTest
{
private string connStr = "";
protected override void Construct(string s)
{
this.connStr = s;
}
#region IEnterpriseServiceTest 成員
//這個屬性表明自動處理事務,如果成功,則自動調用 ContextUtil.SetComplete來完成事務,
//如果事務過程當中發生了問題拋出異常,則自動調用ContextUtil.SetAbort來中止事務處理,
//如果不使用這個屬性則需要自己在程序中手動調用它們來完成或中止事務
//支持事務的方法執行的任務(所執行的代碼)得是支持事務操作的,才能顯出事務的效果來(比如寫數據庫),如果不支持事務,
//則使用這個也無法進行回滾等等(比如寫文件,更改變量的值,只要成功完成後,即使調用ContextUtil.SetAbort也無法對已經完成的操作進行回滾(比如:
//將寫好的文件變回寫之前的狀態,或者將改變的變更變回原值等等)
//另外ContextUtil.EnableCommit表示對事務處理滿意ContextUtil.DisableCommit表示對事務處理不滿意,但都沒有表示事務完成。
//[AutoComplete()]
public string ProceedStr(string str)
{
MySqlConnection conn = null;
try
{
conn = new MySqlConnection(this.connStr);
string cmdStr = "insert into t1(name) values(wo cao ni ma)";
MySqlCommand cmd = new MySqlCommand(cmdStr, conn);
conn.Open();
cmd.ExecuteNonQuery();
cmd.ExecuteNonQuery();
ContextUtil.SetComplete();//這句提交完成不起作用,要以方法最後執行的設置為准
cmd.CommandText = "insert into t1(name) values(hello)";
cmd.ExecuteNonQuery();
ContextUtil.SetComplete();
return "ok";
}
catch (Exception ex)
{
ContextUtil.SetAbort();//如果沒有下面一句,則整個三句將都沒有插入成功
ContextUtil.SetComplete();//這樣執行後,前兩句沒錯的語句成功插入,最後一句沒有插入
throw ex;
}
finally
{
if (conn != null)
conn.Close();
}
}
#endregion
}
}
無組件:
using System;
using System.Collections.Generic;
using System.Text;
using System.EnterpriseServices;
using MySql.Da
ta;
using MySql.Da
ta.MySqlClient;
namespace NoComptESTest
{
public class NoComptTest
{
//沒有組件的服務就是使用ServiceConfig來配置服務,然後調用ServiceDomain.Enter(config)來使用配置創建環境,事務的提交與使用組件的服務是一樣的
//使用ContextUtil或使用[AutoComplete()]屬性來修飾方法,最後再調用ServiceDomain.Leave()來釋放環境
//沒有組件的服務是不能擁有全部的功能,而且調用的程序也不用像有組件的服務那樣的還需要引用System.EnterpriseServices,只需要引用這個程序集就行了
public static bool Execute(bool isAdd)
{
ServiceConfig config = new ServiceConfig();
config.Transaction = TransactionOption.Required;
ServiceDomain.Enter(config);
MySqlConnection conn = null;
try
{
conn = new MySqlConnection("Database=Test;Da
ta Source=sai;Port=3306;User Id=root;Password=1980425");
string cmdText = "insert into t1(name) values(ni ma bi)";
MySqlCommand cmd = new MySqlCommand(cmdText, conn);
conn.Open();
cmd.ExecuteNonQuery();
cmd.ExecuteNonQuery();
cmd.ExecuteNonQuery();
if (isAdd)
ContextUtil.SetComplete();
else
ContextUtil.SetAbort();
return true;
}
catch (Exception ex)
{
ContextUtil.SetAbort();
Console.WriteLine(ex.ToString());
return false;
}
finally
{
if (conn != null)
conn.Close();
ServiceDomain.Leave();
}
}
}
}
調用組件代碼:<