wcf advanced activity development

Upload: rajanikantsingh

Post on 03-Jun-2018

220 views

Category:

Documents


0 download

TRANSCRIPT

  • 8/12/2019 Wcf Advanced Activity Development

    1/30

    Session Code: CV.27

    Integrating WCF andWorkflow, Advanced activity

    development

    Marcel de VriesMicrosoft MVP Team System

    http://blogs.infosupport.co m/marcelvmarce

    [email protected]

    mailto:[email protected]://blogs.infosupport.com/marcelvmailto:[email protected]:[email protected]:[email protected]://blogs.infosupport.com/marcelv
  • 8/12/2019 Wcf Advanced Activity Development

    2/30

    Agenda

    Integrating WCF in workflow Building activities basics Design time behavior

    Type Converters Activity Designer Runtime behavior

    Activity Code Generator Additional features

    Attached Dependency properties Activity Validator

    Summary

  • 8/12/2019 Wcf Advanced Activity Development

    3/30

    Integrating WCF in workflow

    WCF requires a class that implements a servicecontract and that is hosted in a service host

    [ServiceContract(Namespace= "http://www.beyonddotnet.com/WCFTestInterface" )]public interface WCFTEstInterface{

    [OperationContract ]string SayHello();[OperationContract(IsOneWay= true, Action= "DoNothing2") ]void DoNothing();

    }

    public class WCFTEstInterfaceImpl : WCFTEstInterface{

    public string SayHello(){}public void DoNothing(){}

    }

  • 8/12/2019 Wcf Advanced Activity Development

    4/30

    Workflows are classes derived from activityand are hosted in a WorkflowRuntime

    How can we combine the two? Create activities that can hold the service

    operation definitions Generate a class that implements the interfaces

    and applies the correct attributes

    Create an implementation that can bootstrap theload/creation of a workflow when a WCF callcomes in

    Integrating WCF in workflow

  • 8/12/2019 Wcf Advanced Activity Development

    5/30

    Workflow Host e.g IIS

    Integrating WCF in workflowGenerated codehandlingthe incoming call

    Load/Create WF

    Process WF

    Return result

    Client

  • 8/12/2019 Wcf Advanced Activity Development

    6/30

    Activity Component ModelEach activity has an associated set of componentsComponents are associated through attributes on the Activity DefinitionIf not specified, parents attributes are applied

    Required

    Optional(defaults provided)

    [Designer(typeof(MyDesigner))]

    [ActivityCodeGenerator(typeof(MyCodeGen))]

    [ActivityValidator(typeof(MyValidator))]

    public class MyActivity: Activity {...}

    Activity

    CodeGenerator

    Designer

    Validator

    Serializer Services

    Workflow Runtime

  • 8/12/2019 Wcf Advanced Activity Development

    7/30

    Building the activities Design time behavior

    Pick interface using WF type picker dialog Create a dropdown containing methods available on Interface Add parameter that can be bound based on selected method in

    interface

    Generate WCF code that handles incoming call Validate if activities are configured correctly

    Runtime behavior Register an event queue to wait on until notified by generated

    code to start processing

    At continuation bind parameters based on binding expressions Output activity returns results

  • 8/12/2019 Wcf Advanced Activity Development

    8/30

    Implementing Design timebehavior

  • 8/12/2019 Wcf Advanced Activity Development

    9/30

    Design time behavior Interface Property

    Implementing the Interface property Dependency property of type Type Attached a TypeBrowserEditor using attributes

    Need to implement ITypeFilter to show only interfaces we are

    interested in

    public bool CanFilterType( Type type , bool throwOnError){

    // Display only interfacesreturn (type.IsInterface);

    }[Browsable( false )]public string FilterDescription{

    get { return "Choose an interface you want to expose as a ServiceContract" ; }}

  • 8/12/2019 Wcf Advanced Activity Development

    10/30

    Design time behavior Method Property

    Method property needs a custom value provider,since it must show all methods available in theselected interface Done by adding attribute to property providing custom

    TypeProvider When a method is selected in the grid you need

    to trigger that the parameters are exposed to theproperty grid as bindable properties Triggering is done by specifying attribute to the

    Method attribute [RefreshProperties(RefreshProperties.All)]

    And is handled in the designer OnActivityChanged

  • 8/12/2019 Wcf Advanced Activity Development

    11/30

    Design time behavior Parameters property

    Parameters property needs to be a dynamiclist of bindable parameters depending on theavailable arguments of the selected Methodin the interface This is done by creating the Parameters property

    of type WorkflowParameterBindingCollectionand implementing designer behavior

    Designer takes care of adding bindable propertiesto this collection in the PreFilterPropertiesmethod

  • 8/12/2019 Wcf Advanced Activity Development

    12/30

    Design time behavior

    Implementing the designer PreFilterProperties must use reflection to get

    all parameters for the selected method Adds a new PropertyDescriptor for each

    parameter Eacht property is Bindable in the property grid

    Each property has the BindUITypeEditorattached

  • 8/12/2019 Wcf Advanced Activity Development

    13/30

  • 8/12/2019 Wcf Advanced Activity Development

    14/30

    DEMO:Creating the design timebehavior

    Implementing Design time behavior forWCFActivities Type Property Method Property Parameters property

  • 8/12/2019 Wcf Advanced Activity Development

    15/30

    Implementing Runtime behavior Runtime behavior must do the following

    For each incoming message load or create theappropriate workflow

    Yield the thread to the workflow so it can execute until

    it becomes idle in the WCF Input activity Register a synchronization object when output isgenerated by the workflow

    There is an associated output activity Yield the thread again to execute the workflow

    between the input and output activity Binds the message data to parameters set in the designer Communicate back the results of the call when

    synchronization object is signaled

  • 8/12/2019 Wcf Advanced Activity Development

    16/30

    Workflow Host e.g IIS

    Generated codehandlingthe incoming call

    Load/Create WF

    Queue MessageData

    Return result

    Yield Thread

    Register andwait on queue

    Register WaitObject

    Yield Thread

    Dequeue &Bind params

    Wait for WaitObject

  • 8/12/2019 Wcf Advanced Activity Development

    17/30

    Implementing Runtime behavior WCFInput Must register a queue to receive the data

    Done using a base class that handles queue management. Only Implement ProcessQueueItem

    Generated code will pass message data for

    processing in the queue

    protected override bool ProcessQueueItem( ActivityExecutionContext context,object item)

    {

    object [] inputParameters = (object [])item;ProcessParameters(inputParameters);return true ;

    }

  • 8/12/2019 Wcf Advanced Activity Development

    18/30

    Implementing Runtime behavior

    ProcessParameters binds the providedmessage data to the workflow properties

    private void ProcessParameters( object [] inputParameters)

    {MethodInfo methodInfo = InterfaceType.GetMethod(MethodName);int parameterIndex = 0;foreach (ParameterInfo paramInfo in methodInfo.GetParameters()){

    if (Parameters.Contains(paramInfo.Name)){

    WorkflowParameterBinding parameterBinding = Parameters[paramInfo.Name];parameterBinding.Value = inputParameters[parameterIndex++];

    }}

    }

    Activity metadata

    WCF message data

  • 8/12/2019 Wcf Advanced Activity Development

    19/30

    Demo

    Show generic WCF call handling Show Input activity implementation

  • 8/12/2019 Wcf Advanced Activity Development

    20/30

    Implementing Runtime behavior

    Most of the WCF handling can beprogrammed in a base class that handleseach call Only parameter binding is done in the input

    activity itself, rest is WCF plumbing Some code needs to be generated to expose

    the service contract This is done using an ActivityCodeGenerator

    Generate a class that implements the selected methodsignatures in the input activities Add WCF attributes to those methods so they can be

    exposed to WCF

  • 8/12/2019 Wcf Advanced Activity Development

    21/30

    Implementing runtime behavior

    Activity Code Generator Invoked during the compilation cycle of a

    workflow project

    Use CodeDom to add you custom code Use reflector to see what you generated WF Program compilation steps:

    1. XAML deserialization & code generation

    2. Activity Validation3. Activity code Generation4. Code Compilation

  • 8/12/2019 Wcf Advanced Activity Development

    22/30

    Implementing runtime behavior

    What needs to be generated? The call to HandleWCFCall for each input

    activity in the workflow[ServiceContract (Name ="TestWorkflow1" )]public class TestWorkflow1_wcfContractImpl : WCFCallHander { // Methods

    [OperationContract ( Action ="ActivatingCall" )]private string ActivatingCall ()

    {object [] p r m t rs = new object [0];return (string ) base .HandleWCFCall (true , false , typeof (TestWorkflow1 ),

    "WCFTEstInterface" , "ActivatingCall" , "System.String" , parameters);}

    }

    http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.ServiceModel:3.0.0.0:b77a5c561934e089/System.ServiceModel.ServiceContractAttribute/.ctor()http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.ServiceModel:3.0.0.0:b77a5c561934e089/System.ServiceModel.ServiceContractAttribute/property:Name:Stringhttp://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://TestLibrary:1.0.0.0/TestLibrary.TestWorkflow1_wcfContractImplhttp://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://WCFActivities:1.0.0.0:e316e0e29ca8f225/WCFActivities.WCFCallHanderhttp://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.ServiceModel:3.0.0.0:b77a5c561934e089/System.ServiceModel.OperationContractAttribute/.ctor()http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.ServiceModel:3.0.0.0:b77a5c561934e089/System.ServiceModel.OperationContractAttribute/property:Action:Stringhttp://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089/System.Stringhttp://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://TestLibrary:1.0.0.0/TestLibrary.TestWorkflow1_wcfContractImpl/ActivatingCall():Stringhttp://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089/System.Objecthttp://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089/System.Objecthttp://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089/System.Stringhttp://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://WCFActivities:1.0.0.0:e316e0e29ca8f225/WCFActivities.WCFCallHander/HandleWCFCall(Boolean,Boolean,System.Type,String,String,String,Object[]):Objecthttp://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://TestLibrary:1.0.0.0/TestLibrary.TestWorkflow1http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://TestLibrary:1.0.0.0/TestLibrary.TestWorkflow1http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://WCFActivities:1.0.0.0:e316e0e29ca8f225/WCFActivities.WCFCallHander/HandleWCFCall(Boolean,Boolean,System.Type,String,String,String,Object[]):Objecthttp://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089/System.Stringhttp://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089/System.Objecthttp://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089/System.Objecthttp://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://TestLibrary:1.0.0.0/TestLibrary.TestWorkflow1_wcfContractImpl/ActivatingCall():Stringhttp://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089/System.Stringhttp://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.ServiceModel:3.0.0.0:b77a5c561934e089/System.ServiceModel.OperationContractAttribute/property:Action:Stringhttp://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.ServiceModel:3.0.0.0:b77a5c561934e089/System.ServiceModel.OperationContractAttribute/.ctor()http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://WCFActivities:1.0.0.0:e316e0e29ca8f225/WCFActivities.WCFCallHanderhttp://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://TestLibrary:1.0.0.0/TestLibrary.TestWorkflow1_wcfContractImplhttp://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.ServiceModel:3.0.0.0:b77a5c561934e089/System.ServiceModel.ServiceContractAttribute/property:Name:Stringhttp://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.ServiceModel:3.0.0.0:b77a5c561934e089/System.ServiceModel.ServiceContractAttribute/.ctor()
  • 8/12/2019 Wcf Advanced Activity Development

    23/30

    Activity code generation

    Done by building an ActivityCodeGenerator

    You receive a codedom representation ofyour workflow implementation Search for a definition of a class called

    _wcfimpl If not found create one using code dom and adding

    it to the namenspace Add a new method signature using code dom

    to the generated class

  • 8/12/2019 Wcf Advanced Activity Development

    24/30

    Demo

    Show generation using ActivityCodeGenerator

  • 8/12/2019 Wcf Advanced Activity Development

    25/30

    Additional Designtime features

    Attached Properties WCF has some settings you would like to set

    once on each workflow

    Namespace, ServiceName, GeneratedClassName You can use attached properties for this

    purpose Requires designer to add IExtenderProvider during

    initialization for each attached property Requires a ExtenderProvider for each property Value can be retrieved using the GetValue()

    method on the activity you attached the property to

  • 8/12/2019 Wcf Advanced Activity Development

    26/30

    Additional Designtime Features Designer Validation

    A validator can check if the properties that got assigned to youractivity are correct

    Requires you to implement a class derived from ActivityValidator You implement the Validate method

    You apply the validator to the activity using the ActivityValidator attribute At validation you have the full instantiated activity tree at your

    disposal Can do complex validation cross the tree

    Check if an input activity has an associated output activity when retrun

    value != void Your validator is activated in compilation cycle! Therefore validation is normally used for metadata validation

    26

  • 8/12/2019 Wcf Advanced Activity Development

    27/30

    Demo

    Attached properties Activity Validator

  • 8/12/2019 Wcf Advanced Activity Development

    28/30

    Codeplex version

    Codeplex version contains additional feature Correlation based on attributes Leaves the client from knowing and returning the

    message headers At the Data/Operation contract an attribute isadded that will do the correlation

    Done using a WCF behavior

    Required few changes in code gen, since thereyou need to add attributes to the serviceoperations

  • 8/12/2019 Wcf Advanced Activity Development

    29/30

    Q&A

    More information Activities shown today

    www.codeplex.com/WCFActivities

    http://blogs.infosupport.com/marcelv MSDN forums Workflow SDK

    http://www.codeplex.com/WCFActivitieshttp://blogs.infosupport.com/marcelvhttp://blogs.infosupport.com/marcelvhttp://blogs.infosupport.com/marcelvhttp://www.codeplex.com/WCFActivities
  • 8/12/2019 Wcf Advanced Activity Development

    30/30

    Evaluation form

    Vul je evaluatieformulier in en maak kansop een van de prachtige prijzen!!

    Fill out your evaluation form and win one ofthe great prizes!!

    Session Code: CV.27