[K2 Blackpearl] 编写SmartObject Service
SmartObject Service是一个将外部数据导入到SmartObjects的管道,它重写了几个K2 Blackpearl要求的方法。
下面记录我自己编写的一个从ActivityDirectory中读取用户信息的SmartObject Service。
创建SmartObject Service 类
添加引用SourceCode.SmartObjects.Services.ServiceSDK,该DLL位于\\Program Files\K2 blackpearl\Host Server\Bin\,
添加类MySmartObjectService,并继承自ServiceAssemblyBase。重写方法GetConfigSection() , DescribeSchema() , Execute() , and Extend() 。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using SourceCode.SmartObjects.Services.ServiceSDK; using SourceCode.SmartObjects.Services.ServiceSDK.Objects; using SourceCode.SmartObjects.Services.ServiceSDK.Types; using System.Data; namespace Wrox.Custom.SmartService { public class MySmartObjectService : ServiceAssemblyBase { public MySmartObjectService() { } public override string GetConfigSection() { return base.GetConfigSection(); } public override string DescribeSchema() { return base.DescribeSchema(); } public override void Execute() { base.Execute(); } public override void Extend() { //throw new NotImplementedException(); } } }
重写GetConfigSection方法
GetConfigSection方法用于定义配置信息,以便在SmartObject Service实例中读取这些配置。比如数据库链接,WebService链接都可在GetConfigSection方法中定义。
在创建service实例时,会需要填写该方法中注册的所有配置信息(如果是必须项),并实例之间是不共享这些配置信息的。
public override string GetConfigSection() { this.Service.ServiceConfiguration.Add("LDAPServer", true, "LDAP://SERVER/DC"); return base.GetConfigSection(); }
重写DescribeShcema方法
DescribeSchema方法用于定义公用借口。首先设置service的基础信息。
this.Service.Name = "WroxCustomService"; this.Service.MetaData.DisplayName = "Wrox Custom Service"; this.Service.MetaData.Description = "Custom Service for Wrox";
定义ServiceObjects。可定义多个。ServiceObjects可以认为是一个方法集。
ServiceObject so = new ServiceObject(); so.Name = "WroxCustomServiceObject"; so.MetaData.DisplayName = "Wrox Stub Service"; so.MetaData.Description = "Use for Wrox Stub Service"; so.Active = true; this.Service.ServiceObjects.Add(so);
定义ServiceObjects的属性Property。Property用于ServiceObjects中方法的传入和传出参数。
Property property1 = new Property(); property1.Name = "sAMAccount"; property1.MetaData.DisplayName = "User Account"; property1.MetaData.Description = "Identity of user account"; property1.Type = "String.String"; property1.SoType = SoType.Text; so.Properties.Add(property1); Property property2 = new Property(); property2.Name = "EmployeeID"; property2.MetaData.DisplayName = "Employee ID"; property2.MetaData.Description = "employee id of user"; property2.Type = "System.String"; property2.SoType = SoType.Text; so.Properties.Add(property2);
接下来开始定义方法Method。Method的类型包括:Create, Read, Update, Delete, List, and Execute。
Method method1 = new Method(); method1.Name = "FindOne"; method1.MetaData.DisplayName = "FindOne"; method1.MetaData.Description = " find one user"; method1.Type = MethodType.Read; method1.Validation.RequiredProperties.Add(property1); method1.InputProperties.Add(property1); method1.ReturnProperties.Add(property1); method1.ReturnProperties.Add(property2); so.Methods.Add(method1); Method method2 = new Method(); method2.Name = "FindAll"; method2.MetaData.DisplayName = "FindAll"; method2.MetaData.Description = "fin all users"; method2.Type = MethodType.List; method2.Validation.RequiredProperties.Add(property1); method2.InputProperties.Add(property1); method2.ReturnProperties.Add(property1); method2.ReturnProperties.Add(property2); so.Methods.Add(method2);
DescribeSchema方法实现如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public override string DescribeSchema() { this.Service.Name = "WroxCustomService"; this.Service.MetaData.DisplayName = "Wrox Custom Service"; this.Service.MetaData.Description = "Custom Service for Wrox"; ServiceObject so = new ServiceObject(); so.Name = "WroxCustomServiceObject"; so.MetaData.DisplayName = "Wrox Stub Service"; so.MetaData.Description = "Use for Wrox Stub Service"; so.Active = true; this.Service.ServiceObjects.Add(so); Property property1 = new Property(); property1.Name = "sAMAccount"; property1.MetaData.DisplayName = "User Account"; property1.MetaData.Description = "Identity of user account"; property1.Type = "String.String"; property1.SoType = SoType.Text; so.Properties.Add(property1); Property property2 = new Property(); property2.Name = "EmployeeID"; property2.MetaData.DisplayName = "Employee ID"; property2.MetaData.Description = "employee id of user"; property2.Type = "System.String"; property2.SoType = SoType.Text; so.Properties.Add(property2); Method method1 = new Method(); method1.Name = "FindOne"; method1.MetaData.DisplayName = "FindOne"; method1.MetaData.Description = " find one user"; method1.Type = MethodType.Read; method1.Validation.RequiredProperties.Add(property1); method1.InputProperties.Add(property1); method1.ReturnProperties.Add(property1); method1.ReturnProperties.Add(property2); so.Methods.Add(method1); Method method2 = new Method(); method2.Name = "FindAll"; method2.MetaData.DisplayName = "FindAll"; method2.MetaData.Description = "fin all users"; method2.Type = MethodType.List; method2.Validation.RequiredProperties.Add(property1); method2.InputProperties.Add(property1); method2.ReturnProperties.Add(property1); method2.ReturnProperties.Add(property2); so.Methods.Add(method2); return base.DescribeSchema(); }
重写Excute方法
Excute方法决定了ServiceObjects Service执行的操作。
public override void Execute() { try { foreach (ServiceObject so in Service.ServiceObjects) { switch (so.Name) { case "WroxCustomServiceObject": foreach (Method m in so.Methods) { switch (m.Name) { case "FindOne": LoadMethod(so, m); break; case "FindAll": ListMethod(so, m); break; default: throw new Exception("Service Method Undefind"); } } break; default: throw new Exception("Service Object Not Found"); } } } catch (Exception ex) { string errorMsg = Service.MetaData.DisplayName + " Error >> " + ex.Message; this.ServicePackage.ServiceMessages.Add(errorMsg, MessageSeverity.Error); this.ServicePackage.IsSuccessful = false; } // base.Execute(); }
ServiceObject中Method返回数据需要用到ServiceObject的属性ResultTable,在Method返回数据前,需要填充该属性。通过调用ServiceObjects中InitResultTable方法来初始化该属性。
在Load方法中,通过修改ServiceObjects的属性值,最后通过ServiceObjects中BindPropertiesToResultTable方法将数据填充到ResultTable。
private void LoadMethod(ServiceObject so, Method m) { string sAMAccount = string.Empty; string ldap = string.Empty; ADUser user = null; so.Properties.InitResultTable(); sAMAccount = so.Properties["sAMAccount"].Value.ToString(); ldap = Service.ServiceConfiguration["LDAPServer"].ToString(); ADOperate ap = new ADOperate(ldap);//AD的操作类 try { user = ap.FindOne(sAMAccount); } catch (Exception ex) { throw new Exception(ex.Message + "-" + ex.StackTrace); } if (user != null) { so.Properties["sAMAccount"].Value = user.Account; so.Properties["EmployeeID"].Value = user.EmployeeID; } so.Properties.BindPropertiesToResultTable(); }
在ListMethod方法中,在初始化ResultTable之后,就能够往该属性中添加结果。
public void ListMethod(ServiceObject so, Method m) { so.Properties.InitResultTable(); DataTable dtResult = this.ServicePackage.ResultTable; string sAMAccount = so.Properties["sAMAccount"].Value.ToString(); string ldap = Service.ServiceConfiguration["LDAPServer"].ToString(); ADOperate ap = new ADOperate(ldap);//AD操作类 List<ADUser> lstUsers = ap.FindAll(sAMAccount); DataRow dr; foreach (ADUser user in lstUsers) { dr = dtResult.NewRow(); dr["sAMAccount"] = user.Account; dr["EmployeeID"] = user.EmployeeID; dtResult.Rows.Add(dr); } }
重载Extend方法
在多数情况下,不需要重写Extend方法。该方法能够在ServiceObjects实例运行的状态下,修改实例。
public override void Extend() { //throw new NotImplementedException(); }
编译项目。
部署SmartObject Service:传送门
本文版权归菜鸟和博客园共有,欢迎转载,但请注明出处。