创建外部数据服务.docx
- 文档编号:25058586
- 上传时间:2023-06-04
- 格式:DOCX
- 页数:13
- 大小:19.62KB
创建外部数据服务.docx
《创建外部数据服务.docx》由会员分享,可在线阅读,更多相关《创建外部数据服务.docx(13页珍藏版)》请在冰豆网上搜索。
创建外部数据服务
创建外部数据服务
我们现在来到了更加复杂的一节,我们的任务是为外部数据服务创建桥接代码。
宿主必须有这些代码,它才能访问到工作流实例试图传递过来的数据。
我们将使用工具来为工作流创建活动(这在下一节介绍),但对于宿主这边的通信连接来说,却没有现成的工具。
在这里,我们将创建一个稍微简化的连接桥版本(这是对于完整的连接桥架构来说)。
该版本仅仅支持工作流到宿主的通信。
(当我们学到17章时,我们将会创建一个可重用的通用双向连接桥。
)我们在此将创建的连接桥被分成了两个部分:
一是connector,它实现了我们前面已经开发好了的接口;二是service,除了别的事情外,它有一个职责是激发“dataavailable”事件以及提供一个“read”方法,使用该方法来把数据从工作流中取出。
提示:
该代码应由你而不是WF来提供。
我在写本地数据交换服务时提供了该代码,但你要写的代码可以有所不同。
唯一要求是本地数据交换服务实现了通信接口并提供一种机制,用于检索需要交换的数据。
为什么如此复杂?
和传统的.NET对象不同,工作流实例在工作流运行时的范围内执行。
因此进出工作流实例的事件都由工作流运行时进行代理。
工作流运行时必须做这些工作,因为你的宿主应用程序不能把数据发送给已经被持久化或不处在执行状态下的工作流实例。
回到我们的连接桥上,该连接类包含一个字段,工作流将使用要被传回的数据来填充该字段。
对于我们正在创建的本示例应用程序来说,我们不允许并发执行工作流实例,但这仅仅是出于方便。
通常情况下,并没有阻止我们执行并发执行的工作流实例,这些我们将在第17章看到。
当然,每一个工作流实例可能会返回不同的数据,至少它传递的驾驶员会和另一个工作流实例不同。
连接类的职责是实现我们开发的在宿主这边接口,以及不间断地保持这些数据。
当宿主请求该数据时,连接类根据工作流实例ID来确定应正确返回的DataSet是否已经到达。
该服务类为你处理一些任务。
首先,它使用工作流运行时注册该ExternalDataService,以便我们可在宿主和工作流实例间进行通信。
它维护一个连接类的单例副本,并把它自己作为服务提供者绑定到该连接类。
该服务类也充当了工厂(设计模式)的角色,确保我们有一个且仅有一个连接类(实例)。
(假如我们实现了双向的接口,该服务类也会提供一个“write”方法。
)我们现在就来创建这些类。
创建桥接器(bridgeconnector)类
1.在VisualStudio中打开MVDataService项目,定位到MVDataCnnector.cs文件,最后打开该文件。
2.在所定义的名称空间中添加下面的代码:
publicsealedclassMVDataConnector:
IMVDataService
{
privateDataSet_dataValue=null;
privatestaticWorkflowMVDataService_service=null;
privatestaticobject_syncLock=newobject();
}
字段_dataValue用来容纳工作流实例产生的数据。
字段_service用来容纳数据服务对象的单一实例。
_syncLock对象仅仅用来进行线程的同步。
3.下面,我们添加一个static属性来访问该服务对象的单一实例。
代码如下:
WorkflowMVDataService
publicstaticWorkflowMVDataServiceMVDataService
{
get{return_service;}
set
{
if(value!
=null)
{
lock(_syncLock)
{
//Re-verifytheserviceisn'tnull
//nowthatwe'relocked
if(value!
=null)
{
_service=value;
}//if
else
{
thrownewInvalidOperationException("Youmustprovideaserviceinstance.");
}//else
}//lock
}//if
else
{
thrownewInvalidOperationException("Youmustprovideaserviceinstance.");
}//else
}
}
4.我们需要添加一个属性来访问该DataSet,代码如下:
publicDataSetMVData
{
get{return_dataValue;}
}
5.因为连接器类从IMVDataService派生,因此我们必须实现MVDataUpdate方法:
publicvoidMVDataUpdate(DataSetmvData)
{
//Assignthefieldforlaterrecall
_dataValue=mvData;
//Raisetheeventtotriggerhostread
_service.RaiseMVDataUpdateEvent();
}
工作流使用这个方法来把DataSet保存到_dataValue字段中。
它激发事件以通知宿主数据已经准备好了。
该桥接器类的完整代码参见清单8-3。
注意我们这时并没准备去编译整个应用程序,我们还有更多的代码需要添加。
清单8-3完整的MVDataconnector.cs源文件MVDataConnector
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Text;
usingSystem.Workflow.Activities;
usingSystem.Workflow.Runtime;
usingSystem.Data;
namespaceMVDataService
{
publicsealedclassMVDataConnector:
IMVDataService
{
privateDataSet_dataValue=null;
privatestaticWorkflowMVDataService_service=null;
privatestaticobject_syncLock=newobject();
publicstaticWorkflowMVDataServiceMVDataService
{
get{return_service;}
set
{
if(value!
=null)
{
lock(_syncLock)
{
//Re-verifytheserviceisn'tnull
//nowthatwe'relocked
if(value!
=null)
{
_service=value;
}//if
else
{
thrownewInvalidOperationException("Youmustprovideaserviceinstance.");
}//else
}//lock
}//if
else
{
thrownewInvalidOperationException("Youmustprovideaserviceinstance.");
}//else
}
}
publicDataSetMVData
{
get{return_dataValue;}
}
//Workflowtohostcommunicationmethod
publicvoidMVDataUpdate(DataSetmvData)
{
//Assignthefieldforlaterrecall
_dataValue=mvData;
//Raisetheeventtotriggerhostread
_service.RaiseMVDataUpdateEvent();
}
}
}
创建桥接服务(bridgeservice)类
1.再次在VisualStudio中打开MVDataService项目,定位到WorkflowMVDataService.cs文件,打开该文件准备进行编辑。
2.我们创建好了MVDataConnector类,我们还要把下面的代码复制到WorkflowMVDataService.cs文件中:
publicclassWorkflowMVDataService
{
staticWorkflowRuntime_workflowRuntime=null;
staticExternalDataExchangeService_dataExchangeService=null;
staticMVDataConnector_dataConnector=null;
staticobject_syncLock=newobject();
publiceventEventHandler
privateGuid_instanceID=Guid.Empty;
}
3.我们需要具有从类的外部访问_instanceID的能力,因此添加下面的属性:
publicGuidInstanceID
{
get{return_instanceID;}
set{_instanceID=value;}
}
4.我们现在要添加一个静态的工厂方法,我们将用它去创建本类的实例。
我们这样做是为了确保在我们创建本桥接服务的时候,所有重要的事情都已完成。
例如,我们需要确保ExternalDataService服务已被插入到了工作流运行时中。
我们也将添加刚才已经创建好了的桥接器类,并把它作为一个可插拔服务以便工作流能访问到该数据连接器类。
因此,我们在上面一步所添加的属性下面还要添加下面的方法:
CreateDataService
publicstaticWorkflowMVDataServiceCreateDataService(GuidinstanceID,WorkflowRuntimeworkflowRuntime)
{
lock(_syncLock)
{
//Ifwe'rejuststarting,saveacopyoftheworkflowruntimereference
if(_workflowRuntime==null)
{
//Saveinstanceoftheworkflowruntime.
_workflowRuntime=workflowRuntime;
}//if
//Ifwe'rejuststarting,pluginExternalDataExchangeservice
if(_dataExchangeService==null)
{
//Dataexchangeservicenotregistered,socreatean
//instanceandregister.
_dataExchangeService=newExternalDataExchangeService();
_workflowRuntime.AddService(_dataExchangeService);
}//if
//Checktoseeifwehavealreadyaddedthisdataexchangeservice
MVDataConnectordataConnector=(MVDataConnector)workflowRuntime.
GetService(typeof(MVDataConnector));
if(dataConnector==null)
{
//Firsttimethrough,socreatetheconnectorand
//registerasaservicewiththeworkflowruntime.
_dataConnector=newMVDataConnector();
_dataExchangeService.AddService(_dataConnector);
}//if
else
{
//Usetheretrieveddataconnector.
_dataConnector=dataConnector;
}//else
//Pulltheserviceinstanceweregisteredwiththeconnectionobject
WorkflowMVDataServiceworkflowDataService=MVDataConnector.MVDataService;
if(workflowDataService==null)
{
//Firsttimethrough,socreatethedataserviceand
//handittotheconnector.
workflowDataService=newWorkflowMVDataService(instanceID);
MVDataConnector.MVDataService=workflowDataService;
}//if
else
{
//Thedataserviceisstaticandalreadyregisteredwith
//theworkflowruntime.TheinstanceIDpresentwhenit
//wasregisteredisinvalidforthisiterationandmustbe
//updated.
workflowDataService.InstanceID=instanceID;
}//else
returnworkflowDataService;
}//lock
}
5.在前面一节(“创建桥接器类”)我们创建的连接器对象中保存有我们在第4步中创建的该桥接器对象。
我们现在将添加一个静态方法,使用该方法可返回该桥接服务实例。
尽管这些现在看来没有太大必要,但稍后会讲讲我们这样做的理由。
代码如下:
GetRegisteredWorkflowDataService
publicstaticWorkflowMVDataServiceGetRegisteredWorkflowDataService(GuidinstanceID)
{
lock(_syncLock)
{
WorkflowMVDataServiceworkflowDataService=MVDataConnector.MVDataService;
if(workflowDataService==null)
{
thrownewException("Errorconfiguringdataserviceservicecannotbenull.");
}//if
returnworkflowDataService;
}//lock
}
6.下面我们将添加我们(私有属性)的构造器和析构器。
有了桥接器类后,我们需要确保在桥接器对象和桥接服务对象间不会造成循环的引用。
你需要添加下面的代码:
WorkflowMVDataService和~WorkflowMVDataService
privateWorkflowMVDataService(GuidinstanceID)
{
_instanceID=instanceID;
MVDataConnector.MVDataService=this;
}
~WorkflowMVDataService()
{
//Cleanup
_workflowRuntime=null;
_dataExchangeService=null;
_dataConnector=null;
}
7.尽管我们为桥接服务类添加了一些重要的东西,但还没有把ExternalDataService引入工作流运行时中,我们仍然要添加一些代码,以使工作流运行时具有读取数据并返回给宿主应用程序的能力。
桥接器对象实际上是维持该连接状态,但宿主使用这个服务来获得要访问的数据。
下面是我们要添加的read方法:
publicDataSetRead()
{
return_dataConnector.MVData;
}
8.要为我们的桥接服务添加的最后的功能块是一个方法,它激发“机动车数据更新(motorvehicledataupdate)”事件。
工作流使用这个方法来为宿主发送一个通知,告知要挑选的数据已经获取完了。
代码如下:
publicvoidRaiseMVDataUpdateEvent()
{
if(_workflowRuntime==null)
_workflowRuntime=newWorkflowRuntime();
_workflowRuntime.GetWorkflow(_instanceID);//loadspersistedworkflowinstances
if(MVDataUpdate!
=null)
{
MVDataUpdate(this,newMVDataAvailableArgs(_instanceID));
}//if
}
完整的桥接服务代码参见清单8-4:
清单8-4完整的WorkflowMVDataService.cs源文件WorkflowMVDataService
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Text;
usingSystem.Workflow.Activities;
usingSystem.Workflow.Runtime;
usingSystem.Data;
namespaceMVDataService
{
publicclassWorkflowMVDataService
{
staticWorkflowRuntime_workflowRuntime=null;
staticExternalDataExchangeService_dataExchangeService=null;
staticMVDataConnector_dataConnector=null;
staticobject_syncLock=newobject();
publiceventEventHandler
privateGuid_instanceID=Guid.Empty;
publicGuidInstanceID
{
get{return_instanceID;}
set{_instanceID=value;}
}
publicstaticWorkflowMVDataServiceCreateDataService(GuidinstanceID,WorkflowRuntimeworkflowRuntime)
{
lock(_syncLock)
{
//Ifwe'rejuststarting,saveacopyoftheworkflowruntimereference
if(_workflowRuntime==null)
{
//Saveinstanceoftheworkflowruntime.
_workflowRuntime=workflowRuntime;
}//if
//Ifwe'rejuststarting,pluginExternalDataExchangeservice
if(_dataExchangeService==null)
{
//Dataexchangeservicenotregistered,socreatean
//instanceandregister.
_dataExchangeService=newExternalDat
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 创建 外部 数据 服务