Learn About Microsoft .NET Framework 3.5

These questions are based on 70-504: TS: Microsoft .NET Framework 3.5 – Windows Workflow Foundation (C# .NET).

A Self Test Software Practice Test

Objective: Create and host workflows.
Sub-objective: Create state machine workflows.

Single answer, multiple-choice

You are designing a Windows Workflow Foundation (WF) application using the Microsoft .NET Framework 3.5. The WF application will use a state machine workflow that represents customer accounts. A customer account can be in one of the following states:

•    Created: Initial state for new customers.
•    Active: Customer can use the account for new purchases.
•    Inactive: Customers can view their purchase history but cannot make new purchases.
•    Canceled: Customers cannot make purchases or view purchase history, and all information associated with that account is removed.

Which code should you use to create and add these state activities to the workflow?

A.    public enum CustomerAccountState {
Created, Active, Inactive, Cancelled
}

public class CustomerAccountStateMachineWorkflow :
StateMachineWorkflow {
public CustomerAccountStateMachineWorkflow () {
this.States.Add( CustomerAccountState.Created );
this.States.Add( CustomerAccountState.Active );
this.States.Add( CustomerAccountState.Inactive );
this.States.Add( CustomerAccountState.Cancelled );
}
}
B.    public class CustomerAccountStateMachineWorkflow :
StateMachineWorkflow {
private StateActivity created = new StateActivity();
private StateActivity active = new StateActivity();
private StateActivity inactive = new StateActivity();
private StateActivity cancelled = new StateActivity();
public CustomerAccountStateMachineWorkflow () {
this.Activities.Add( created );
this.Activities.Add( active );
this.Activities.Add( inactive );
this.Activities.Add( cancelled );
}
}
C.    public class CustomerAccountStateMachineWorkflow :
StateMachineWorkflowActivity {
private StateActivity created = new StateActivity();
private StateActivity active = new StateActivity();
private StateActivity inactive = new StateActivity();
private StateActivity cancelled = new StateActivity();
public CustomerAccountStateMachineWorkflow () {
this.Activities.Add( created );
this.Activities.Add( active );
this.Activities.Add( inactive );
this.Activities.Add( cancelled );
}
}
D.    public enum CustomerAccountState {
Created, Active, Inactive, Cancelled
}

public class CustomerAccountStateMachineWorkflow :
StateMachineWorkflowActivity {
public CustomerAccountStateMachineWorkflow () {
this.States.Add( CustomerAccountState.Created );
this.States.Add( CustomerAccountState.Active );
this.States.Add( CustomerAccountState.Inactive );
this.States.Add( CustomerAccountState.Cancelled );
}
}

Answer:
C

Tutorial:
To create and add the required state activities to the state machine workflow, you should use the following code:

public class CustomerAccountStateMachineWorkflow :
StateMachineWorkflowActivity {
private StateActivity created = new StateActivity();
private StateActivity active = new StateActivity();
private StateActivity inactive = new StateActivity();
private StateActivity cancelled = new StateActivity();
public CustomerAccountStateMachineWorkflow () {
this.Activities.Add( created );
this.Activities.Add( active );
this.Activities.Add( inactive );
this.Activities.Add( cancelled );
}
}

To create a state machine workflow, you should first create a class derived from the StateMachineWorkflowActivity class. Next, create a StateActivity object for each state and set the Name property of each StateActivity object to identify the object within the workflow. Then, within the constructor of the workflow, you should add each StateActivity object to the Activities collection by using the Add method.

You should not use the code segments that use an enumeration for each state because you must create StateActivity objects to add them to the Activities collection of a state machine workflow. If you use these code segments, they will not compile.

You should not use the code segment that has the workflow class to derive from the StateMachineWorkflow class because no such class exists. To create a state machine workflow, you should derive from the StateMachineWorkflowActivity class.

References:

MSDN Library > .NET Framework 3.5 > Windows Workflow Foundation > Windows Workflow Foundation Programming Guide > Developing Workflows > Workflow Authoring Styles > State Machine Workflows

MSDN Library > .NET Framework Class Library > System.Workflow.Activities Namespace > StateMachineWorkflowActivity Class

Objective: Communicate with workflows.
Sub-objective: Consume services from a workflow.

Single answer, multiple-choice

Using the Microsoft .NET 3.5 Framework, you develop a Windows Workflow Foundation (WF) application that handles account transfers, withdrawals and deposits between regional bank branches. You have developed a sequential workflow to verify and apply all pending transactions for each bank within the region.

Account information and actions are provided by a Web service located in an extranet shared between bank branches. You use the Web service in the workflow to apply all wire transfers at the end of the day. (Click the Exhibit(s) button.)

You need to ensure that the InvokeDebitWS and InvokeCreditWS activities use the same proxy instance when processing a wire transfer. However, a unique session should be created for each wire transfer.

What should you do?

A.    Set the SessionId property to null in both the InvokeDebitWS and InvokeCreditWS activities.
B.    Set the SessionId property to the WorkflowInstanceId property in both the InvokeDebitWS and InvokeCreditWS activities.
C.    Add the following code to the SetAccountParams_ExecuteCode event handler:
string sessionID = WorkflowInstanceId.ToString();
InvokeDebitWS.SessionId = sessionID;
InvokeCreditWS.SessionId = sessionID;
D.    Add the following code to the SetAccountParams_ExecuteCode event handler:
string sessionID = new Guid().ToString();
InvokeDebitWS.SessionId = sessionID;
InvokeCreditWS.SessionId = sessionID;

Answer:
D

Tutorial:
To ensure that two InvokeWebServiceActivity activities use the same Web proxy instance, you should set the SessionId property to the same value. To ensure each iteration generates a unique session with a new Web service proxy, you should add a Code activity that executes code similar to the following:

string sessionID = new Guid().ToString();
InvokeDebitWS.SessionId = sessionID;
InvokeCreditWS.SessionId = sessionID;

This code ensures the InvokeDebitWS and InvokeCreditWS activities share the same proxy instance, but also creates a unique session ID for each transfer using the Guid class.

You should not set the SessionId property to null in both InvokeWebServiceActivity activities because this setting will generate a new Web service proxy instance for each activity and force a new session when the activities are executed.

You should not set the SessionId property to the WorkflowInstanceId property in both InvokeWebServiceActivity activities because this identifier will remain the same value for the lifespan of the workflow instance. The WorkflowInstanceId property uniquely identifies a workflow within a workflow runtime. By setting the SessionId property to the WorkflowInstanceId property’s value, both the InvokeDebitWS and InvokeCreditWS activities would share the same proxy for all transfers. Also, you must convert the WorkflowInstanceId property from a Guid object to a string before setting the SessionId property.

References:

MSDN Library > .NET Development > .NET Framework 3.5 > Windows Workflow Foundation > Windows Workflow Foundation Programming Guide > Developing ASP.NET Workflow Applications > Invoking Web Services from a Workflow

MSDN Library > .NET Framework Class Library > System.Workflow.Activities Namespace > InvokeWebServiceActivity Class > InvokeWebServiceActivity Properties > SessionId Property

Objective: Create and configure custom activities.
Sub-objective: Create custom activities.

Single answer, multiple-choice

You are using version 3.5 of the Microsoft .NET Framework. You are creating a simple workflow activity to write messages to a custom event log. The activity should allow developers to specify an event source, log and entry message in the Properties window. The custom activity should require the least amount of developer effort. What should you do?

A.    Create a class derived from the SequenceActivity class.
Create class instances of DependencyProperty class for the event source, log and entry message.
Create a property for each DependencyProperty instance.
Override the Execute method to write to the custom event log.
B.    Create a class derived from the Activity class.
Create class instances of DependencyProperty class for the event source, log and entry message.
Create a property for each DependencyProperty instance.
Override the Execute method to write to the custom event log.
C.    Create a class derived from the SequenceActivity class.
Create public properties for the event source, log and entry message.
Override the OnStatusChanged method to write to the custom event log.
D.    Create a class derived from the Activity class.
Create class instances of DependencyProperty for the event source, log and entry message.
Create a property for each DependencyProperty instance.
Override the OnStatusChanged method to write to the custom event log.

Answer:
B

Tutorial:
To create a simple workflow activity with the least amount developer effort, you should create a class derived from the Activity class, add class instances of the DependencyProperty class for each property in the Properties window, add a property for each DependencyProperty instance and override the Execute method to perform its work. This is illustrated for this scenario below:

public class EventLogActivity : Activity {
public static DependencyProperty SourceProperty =
DependencyProperty.Register( “Source”, typeof( String ), typeof( EventLogActivity ) );
public static DependencyProperty LogProperty =
DependencyProperty.Register( “Log”, typeof( String ), typeof( EventLogActivity ) );
public static DependencyProperty EntryProperty =
DependencyProperty.Register( “Entry”, typeof( String ),
typeof( EventLogActivity ) );

[Browsable(true)]
[Category(“Activity”)]
public string Source {
get { return (string) base.GetValue( EventLogActivity.SourceProperty ); }
set { base.SetValue( EventLogActivity.SourceProperty, value ); }
}

[Browsable(true)]
[Category(“Activity”)]
public string Log {
get { return (string) base.GetValue( EventLogActivity.LogProperty ); }
set { base.SetValue( EventLogActivity.LogProperty, value ); }
}

[Browsable( true )]
[Category( “Activity” )]
public string Entry {
get { return (string) base.GetValue( EventLogActivity.EntryProperty ); }
set { base.SetValue( EventLogActivity.EntryProperty, value ); }
}
protected override ActivityExecutionStatus Execute ( ActivityExecutionContext executionContext ) {
if ( !EventLog.SourceExists( this.Source ) )
EventLog.CreateEventSource( this.Source, this.Log );
EventLog log = new EventLog( this.Log );
log.Source = this.Source;
log.WriteEntry( this.Entry );
log.Close();
return ActivityExecutionStatus.Closed;
}
}

You should not create a class derived from the SequenceActivity class because this technique will result in more developer effort than required for a simple workflow activity. You should derive from the SequenceActivity class when creating a custom composite activity in which each child activity must be scheduled in a linear fashion, one after the other. In this scenario, you do not have any child activities, so you should derive from the Activity class to minimize developer effort.

You should not override the OnStatusChanged method to perform work within a custom activity because this is the default event handler associated with the StatusChanged event. The StatusChanged event only indicates the activity runtime has changed, providing an ActivityExecutionStatusChangedEventArgs.ActivityExecutionStatus property.

The status indicates whether the activity has been initialized, is executing, cancelling, compensating, faulting or has closed. You should override the Execute method and provide the value for execution status to indicate the work a custom activity should perform.

References:

MSDN Library > .NET Development > .NET Framework 3.5 > Windows Workflow Foundation > Windows Workflow Foundation Programming Guide > Developing Workflow Activities > Creating Custom Activities

MSDN Library > .NET Development > .NET Framework 3.5 > Windows Workflow Foundation > Windows Workflow Foundation Programming Guide > Developing Workflow Activities > Creating Custom Activities > Using Activity Properties

Objective: Apply rules and conditions.
Sub-objective: Write rule sets.

Multiple answer, multiple-choice

In a Windows Workflow Foundation (WF) application, you are defining a declarative rule condition using the Microsoft .NET Framework 3.5. The rule will be used in a workflow that maintains stock inventory for an office supply warehouse.

You need to define a rule to verify that the stock level of a product has not fallen below the product’s defined reorder point. If a product’s stock level is lower than the reorder point, the product should be reordered to replenish existing supplies. Product reorders also are dependent upon the stock priority level. The stock priority level for a product is a public field in the workflow. The field uses a value in the PriorityLevel enumeration.

Which expression classes should you use to reference the stock priority level? (Choose two. Each correct answer is part of the complete solution.)

A.    CodeIndexerExpression
B.    CodeDefaultValueExpression
C.    CodeTypeReferenceExpression
D.    CodeTypeReferenceExpression

Answer:
C, D

Tutorial:
You should use the CodeTypeReferenceExpression and CodeFieldReferenceExpression classes to reference the stock priority level. The CodeFieldReferenceExpression and CodePropertyReferenceExpression classes refer to fields and properties associated with an object, respectively.

In this scenario, the stock priority level is a public field that uses a custom enumeration. To reference the field, you should use the CodeFieldReferenceExpression class and to reference the value, you need to specify the enumeration with the CodeTypeReferenceExpression class. The CodeTypeReferenceExpression class refers to a data type and is required for non-primitive types. You would use the CodePrimitiveExpression class to refer to primitive data types.

You cannot use the CodeIndexerExpression class to reference the stock priority level because it is not an indexer. You would use the CodeIndexerExpression class to reference a non-array indexer associated with a class or object.

You should not use the CodeDefaultValueExpression class to reference the stock priority level because you need to compare the actual value of the stock priority level, not its default value. You would use the CodeDefaultValueExpression class to create default values for data types.

References:

MSDN Library > .NET Framework 3.5 > Windows Workflow Foundation > Windows Workflow Foundation Programming Guide > Developing Workflows > Using RuleSets in Workflows > Declarative RuleSets

MSDN Library > .NET Framework Class Library > System.CodeDom Namespace > CodeTypeReferenceExpression Class

MSDN Library > .NET Framework Class Library > System.CodeDom Namespace > CodeFieldReferenceExpression Class

Objective: Manage transactions and compensations.
Sub-objective: Perform exception handling.

Single answer, multiple-choice

You are using version 3.5 of the Microsoft .NET Framework. You use the following code to instantiate a Windows Workflow Foundation (WF) runtime for sequential workflows:

using (WorkflowRuntime wfRuntime = new WorkflowRuntime()) {
//Instantiate and run workflows
}

You want to handle any exceptions that are thrown by workflows using the runtime. What should you do?

A.    Add an event handler for the runtime’s WorkflowTerminated event.
B.    Add an event handler for the runtime’s WorkflowAborted event.
C.    Add an event handler for the runtime’s WorkflowSuspended event.
D.    Start each workflow within a try…catch block, specifying the System.Exception exception.

Answer:
A

Tutorial:
To handle any exceptions thrown by workflows in a runtime, you should use the WorkflowTerminated event. The WorkflowTerminated event is raised by a TerminateActivity activity or is raised when an unhandled exception is thrown in a workflow. You would use the following code to create an event handler for the WorkflowTerminated event:

private void handleExceptions ( object sender, WorkflowTerminatedEventArgs e ) {
//Handle exceptions
}

You should not add an event handler for the runtime’s WorkflowAborted event because this event is raised when a workflow is stopped in the middle of processing and not necessarily when unhandled exceptions are thrown. Unlike .NET exception handling, the WF runtime schedules exceptions in a queue so that the workflow can continue execution to the next available activity. A WorkflowAborted event would be raised only when a workflow is explicitly aborted by the workflow host or if the workflow runtime cannot terminate the workflow.

You should not add an event handler for the runtime’s WorkflowSuspended event because this event is raised when a workflow is paused but still resumable, not when an unhandled exception is thrown. The WorkflowSuspended event is raised by the workflow host or by a SuspendActivity activity explicitly, or by the workflow runtime when dynamic changes are being applied. An exception would not suspend a workflow.

You should not start each workflow within a try…catch block because although this technique will catch workflow framework errors, it will disrupt the workflow host logic. It is a recommended approach to handle events explicitly if possible, rather than use the overhead exception handling. You should use the WorkflowTerminated event to handle exceptions thrown by workflows.

References:

MSDN Library > .NET Framework 3.5 > Windows Workflow Foundation > Windows Workflow Foundation Programming Guide > Developing Workflow-Enabled Applications > Creating a Workflow Host Application > Creating the WorkflowRuntime

MSDN Library > .NET Framework 3.5 > Windows Workflow Foundation > Windows Workflow Foundation Programming Guide > Developing Workflow-Enabled Applications > Creating a Workflow Host Application > Processing WorkflowRuntime Events

Like what you see? Share it.Share on Google+Share on LinkedInShare on FacebookShare on RedditTweet about this on TwitterEmail this to someone
cmadmin

ABOUT THE AUTHOR

Posted in Archive|

Comment: