06 December 2007

Hosting a Window Form Control in a SharePoint WebPart

Some months ago I posted about Hosting a Windows Form Control in a web page. I explained there how we can run a WinForm control from Internet Explorer by hosting it in a web page using the <object> tag. Now suppose you want to use the same solution in a custom web part that is included in a Sharepoint site. I will describe here where the control library should be placed and how it can be referenced from the web part.

When we develop a custom web part, we place its resources under the _wpresources web site, into a folder named <WebPartAssemblyName>/<WebPartAssemblyVersion>__<PublicKeyToken>. You can create there a subfolder (named "bin" por example) to place the win control assembly. This folder must have execute permissions set to Script Only (not Script and Executables as is the default under a SharePoint site). The picture bellow shows the resulting structure when placing the win form control assembly in a web part called MyCustomWebPart that is part of the MyCustomWebParts assembly: ...

Read full article

30 October 2007

CCF HAT - Making use of DDAs from Legacy Adapters

Although Data Driven Adapters (DDAs) are mainly designed for Automation Adapters in HAT, we can make use of them from legacy adapters, too. Here's an example of an external VB application, which is configured to use a legacy application adapter and a WinDataDrivenAdapter with the corresponding bindings:

<?xml version="1.0" encoding...

Read full article

26 October 2007

CCF 2008 Hosted Application Toolkit

The Hosted Application Toolkit (HAT) is a new component of CCF 2.6 (2008) that facilitates the task of automating the UI of the hosted applications. It consists of two main parts: the Data Driven Adapters (DDA) and the Automations (WF workflows) that automates the hosted application using the DDAs.

Data Driven Adapters

DDAs must inherit from DataDrivenAdapterBase in Microsoft.Ccf.HostedApplicationToolkit. CCF supports two implementations out of the box: WinDataDrivenAdapter and WebDataDrivenAdapter. We can inherit from any of the three to extend the DDA as necessary. The methods the DDAs expose to manipulate the hosted application UI are ExecuteControlAction, FindControl, GetControlValue and SetControlValue. These methods take a friendly name as parameter and lets the application adapters interact with the hosted application UI abstracting from the details of how to obtain the control from that friendly name. The mapping between the controls' friendly names and the directions for the DDA to finding them is called Data Driven Adapter Binding and is part of the hosted app initialization string:...

Read full article

08 October 2007

Silverlight article published this month

My colleagues Ariel Neisen, Federico GarcĂ­a, Rodolfo Finochietti and I wrote the cover article of the #42 edition of the .Code Magazine (in Spanish) about Silverlight. The article talks about this new technology's fundamentals, architecture, programming tools, advanced features, code samples and a lot more.

01 October 2007

Choosing the right WCF binding

A WCF binding is the endpoint component that defines how the client needs to communicate with the service. It groups settings such as underlying transport protocol, security requirements, and message encoding.

WCF provides nine built-in bindings:

  1. BasicHttpBinding: Basic web service communication. Exposes WCF services as legacy ASMX web services. Used for interoperability. No security by default.
  2. WSHttpBinding: Web services with WS-* support. Supports transactions and reliable messaging.
  3. WSDualHttpBinding...

Read full article

28 September 2007

CCF 2008 New Features

The 3.0 version of the Customer Care Framework (CCF) is out! Among its new features we'll find:

  • CCF web services migrated to Windows Communication Foundation (WCF).
  • Agent Desktop use of Composite Application Block (CAB).
  • Hosted Application Toolkit (HAT): new sub-system for providing UI automation, that makes use of Workflow Foundation (WF) and Active Accessibility.
  • ClickOnce support.
  • Dynamic Applications: 3rd category of hosted applications that allow an agent to dynamically launch or close a hosted application on-demand, via the UI or programmatically in code. ...

Read full article

Hosting a Windows Form Control in a web page

Although it is not the most common use of it, it is possible to host a Windows Form Control in a Web Page and run it from within Internet Explorer. This allows to build powerful client side functionality with all the advantages of using the .Net framework and executing the control in the client side. Of course there are some restrictions that cannot be left aside. At least the .Net framework must be installed on the client for the control to run. In addition, it is possible that some permission must...

Read full article

WPF Accessibility

Windows Presentation Foundation (WPF) provides a very interesting API for Accessibility called Microsoft UI Automation. It allows programmatic access to most user interface elements on the desktop, addressing the needs of assistive technology products and also for User Interface (UI) tests automation.

The framework provides solutions for both accessibility providers and clients, and it is conformed of four main components (see UI Automation Overview):

  1. The Provider API (UIAutomationProvider.dll and UIAutomationTypes.dll) defines a ...

Read full article

Also blogging @ weblogs.asp.net

Earlier this month I opened an account to start blogging at weblogs.asp.net. I moved the latest contents from here to there, and I will be cross-posting future entries to have both blogs synchronized. Check it out: http://weblogs.asp.net/spano/.

10 June 2007

Working around VSTO SE's lack of document-customization for Excel 2007

I've been doing some research on Visual Studio Tools for Office (VSTO) and Excel 2007 recently and found out that some very interesting features available in previous versions of VSTO for Excel 2003 are not available for Excel 2007. Here's a summary of the current situation and the workarounds I figured out.

State of the Art

VSTO has basically two kinds of Excel add-ins: document-level customization an application-level add-ins.

The document-level customization lets you customize an Excel workbook and also reference the Application to add buttons to the command bar and so forth. The resulting add-in will be only available to the customized workbook. The great benefit of document-level customization is that you can add controls to the spreadsheets within Visual Studio, being these controls part of the VSTO object model. The VSTO objects are wrappers around the Interop ones and they add very interesting functionality, like events and databinding. The VSTO controls are in the Microsoft.Office.Tools.Excel namespace whereas the Interop ones are in Microsoft.Office.Interop.Excel.

Document-level customization project template

Document-level customization project

On the other and, an application-level add-in is, as its name implies, always visible for the host Application regardless of the opened workbook. The only class added by Visual Studio is the TheAddin one, no workbook or worksheet editors are provided. The VSTO controls are not available neither. All Excel objects that we can get access through TheAddin class are from the Microsoft.Office.Interop.Excel API.

Application-level add-in project template

Application-level add-in project

The problem is that, whereas document-level customization is available for Excel2003, is not yet available for Excel 2007. So, the spreadsheet editor is not available within Visual Studio and the VSTO extended controls cannot be used. The table below shows which kinds of add-in are available for each product combination (see Features available by product combination for the complete table listing all Office applications).


VSTO 2005 or Visual Studio Team System VSTO 2005 SE installed with VSTO 2005 or Visual Studio Team System VSTO 2005 SE installed with Visual Studio 2005 Professional Edition
Document-level customizations Excel 2003 Excel 2003 Not available
Application-level add-ins Not available

Excel 2003

Excel 2007

Excel 2003

Excel 2007

Workarounds

In order to make a document-level customization (or at least something similar) to target Excel 2007 I found out that some of the following things can be done:

1- Develop for Excel 2003 and deploy in Excel 2007

It is possible to develop a document-level customization in Visual Studio for Excel 2003 using VSTO 2005. The resulting customized document can then be opened in Excel 2007 in compatibility mode with the same functionality. The drawbacks of this approach is that Excel 2003 needs to be installed in the developer's machine and that you won't have Office 2007 features like custom panes and ribbon extensibility available.

2- Develop for Excel 2007 with VSTO SE and try to emulate the document-level customization.

In order to target Excel 2007, VSTO SE is needed and the only option by the moment is to create an application level add-in. For emulating the document customization you can create an Excel's template file within Excel application, add the desired named ranges, tables, graphics, etc...and then access these controls trough the add-in's code to make custom automation. The drawback of this approach is that the extended functionality of VSTO's controls is not available. For example, you won't be able to use the ListObject databinding support. In order to access the workbook controls, the Interop API must be used. Another drawback, is that the Interop API is not as well documented as the VSTO's.

3- Develop an application-level add-in for Excel 2007 and create the VSTO's objects from code.

Actually I'm not sure wheter this is really a choice, since I couldn't make it work. What I tried here was to create a new instance of a VSTO worksheet to wrap an Interop worksheet. In ThisAddin class I have the following code:

using Excel = Microsoft.Office.Interop.Excel;

using Vsto = Microsoft.Office.Tools.Excel;

namespace ExcelAddIn1

{

public partial class ThisAddIn

{

private void ThisAddIn_Startup(object sender, System.EventArgs e)

{

#region VSTO generated code

this.Application = (Excel.Application)Microsoft.Office.Tools.Excel.ExcelLocale1033Proxy.Wrap(typeof(Excel.Application), this.Application);

#endregion

try

{

Excel.Worksheet newSheet = (Excel.Worksheet)this.Application.ActiveWorkbook.Worksheets.Add(Type.Missing, Type.Missing, Type.Missing, Type.Missing);

Microsoft.Office.Tools.Excel.Worksheet extendedSheet = GetExtendedWorksheet(newSheet);

extendedSheet.Controls.AddNamedRange(extendedSheet.Range["A1","C2"], "NamedRange");

}

catch (Exception ex) {

MessageBox.Show(ex.ToString());

}

}

private Vsto.Worksheet GetExtendedWorksheet(Excel.Worksheet nativeWorksheet)

{

//Get the IHostItemProvider instance.

Microsoft.VisualStudio.Tools.Applications.Runtime.IHostItemProvider hostItemProvider = (Microsoft.VisualStudio.Tools.Applications.Runtime.IHostItemProvider)

RuntimeCallback.GetService(typeof(Microsoft.VisualStudio.Tools.Applications.Runtime.IHostItemProvider));

//Create the new worksheet and return it to calling function.

return new Vsto.Worksheet(hostItemProvider, RuntimeCallback, nativeWorksheet.CodeName,

null, nativeWorksheet.Name);

}

But, when trying to add the NamedRange to the extended worksheet this Exception is thrown:

This document might not function as expected because the following control is missing: Sheet4. Data that relies on this control will not be automatically displayed or updated, and other custom functionality will not be available. Contact your administrator or the author of this document for further assistance.
at Microsoft.Office.Tools.Excel.Worksheet.GetObjects()
at Microsoft.Office.Tools.Excel.Worksheet.GetPrimaryControl()
at Microsoft.Office.Tools.Excel.Worksheet.get_Range()
at ExcelAddIn1.ThisAddIn.ThisAddIn_Startup(Object sender, EventArgs e) in C:\...\Projects\ExcelAddIn1\ExcelAddIn1\ThisAddIn.cs:line 26

Conclusion

Although VSTO's document-level customization is not available for Excel 2007 yet, there still are some choices for developing add-ins targeting this application version. Besides, the good news is that this lack will be supplied soon. VSTO "Orcas" will provide document-level customization for Excel 2007 within its new features. So, anyway, it's just a matter of time...

16 May 2007

Developing a Custom Property Comparison Validator using Entlib's VAP

 Here's a sample scenario where, in an application using Entlib's Validation Application Block (VAP), the validation of an entity's member depends on the value of  another property. In this case the entity I want to validate has two properties. Using the attributes approach to support validation, the entity's code looks like this:

public class MyEntity

{

    private string myVar1;

 

    [NotNullValidator()]

    [StringLengthValidator(0, 20, MessageTemplate = "MyProperty1 must be less than 20 characters length")]

    public string MyProperty1

    {

        get { return myVar1; }

        set { myVar1 = value; }

    }

 

    private string myVar2;

 

    [MyProp2Validator()]

    public string MyProperty2

    {

        get { return myVar2; }

        set { myVar2 = value; }

    }

}

The validators for Property1 are built in validators, no big deal with that. The thing here is that I want the second property to be validated against the value of the first one. Let’s say, for example, that Property2 is valid if it begins with the value of Property1.

Although the VAP ships with a PropertyComparisonValidator, it is limited to comparisons of type =, !=, >, >=, <>. So it seems that a custom validator has to be made. But how to obtain the actual value of Property1 from the Property2's custom validator?

One approach is to use reflection. Using reflection the DoValidate method of MyProperty2Validator would look something like this:

protected override void DoValidate(string objectToValidate, object currentTarget, string key, ValidationResults validationResults){

    //obtain the other property value through reflection

    PropertyInfo prop = currentTarget.GetType().GetProperty("MyProperty1");

    string myProp1Value = prop.GetValue(currentTarget, null) as string;

    //some custom logic here

    if (! objectToValidate.StartsWith( myProp1Value ){

        LogValidationResult(validationResults,"msg",currentTarget,key);

    }

}

But the dropdown of using reflection is that it wouldn't work with UI integration.

What do work with integration is what the built-in PropertyComparisonValidator does, and that is using the ValueAccess class. The ValueAccess class allow us to find other members in an integration friendly way throuhg its GetValue method. See how this is done in our Property2 valdiator:

[ConfigurationElementType(typeof(MyProp2ValidatorData))]

class MyProp2Validator : Validator<string> {

    private ValueAccess valueAccess;

    internal const string OtherPropName = "MyProperty1";

 

    public MyProp2Validator(ValueAccess valueAccess):base (Resources.MyProp2ValidatorMessageTemplate,null){

        this.valueAccess = valueAccess;

    }

 

    protected override void DoValidate(string objectToValidate, object currentTarget, string key, ValidationResults validationResults){

        object myProp1;

        string valueAccessFailureMessage;

        //try to obtain the value of property 1.

        if (!this.valueAccess.GetValue(currentTarget, out myProp1, out valueAccessFailureMessage)) {

            base.LogValidationResult(validationResults, string.Format(CultureInfo.CurrentUICulture, Resources.MyProp2ValidatorFailureToRetrieveProp1, new object[] { this.valueAccess.Key, valueAccessFailureMessage }), currentTarget, key);

        }

        else {

            //custom validation logic between prop1 and prop2

            if (!objectToValidate.StartsWith((string)myProp1)) {

                base.LogValidationResult(validationResults, string.Format(CultureInfo.CurrentUICulture, this.MessageTemplate, new object[] { objectToValidate, myProp1 }), currentTarget, key);

            }

        }

    }

 

    protected override string DefaultMessageTemplate {

        get { return Resources.MyProp2ValidatorDefaultMessageTemplate; }

    }

}

What’s left is to provide the ValueAccess to the validator’s constructor. This is done in the MyProp2ValidatorAttribute class, if using attributes to place validators, or in the MyProp2ValidatorData if using configuration files. MyProp2ValidatorAttribute would look like this:

public class MyProp2ValidatorAttribute : ValueValidatorAttribute

{

    protected override Validator DoCreateValidator(Type targetType)

    {

        throw new InvalidOperationException("A member value access builder is needed.");

    }

 

    protected override Validator DoCreateValidator(Type targetType, Type ownerType, MemberValueAccessBuilder memberValueAccessBuilder)

    {

        PropertyInfo propertyInfo = ownerType.GetProperty(MyProp2Validator.OtherPropName);

        if (propertyInfo == null)

        {

            throw new InvalidOperationException(String.Format(Resources.MyProp2ValidatorAttributeCouldNotFindProperty, new string[] { ownerType.Name, MyProp2Validator.OtherPropName }));

        }

        return new MyProp2Validator(memberValueAccessBuilder.GetPropertyValueAccess(propertyInfo));

    }

}

Finally, you can test the validation logic using the following code:

private void buttonValidate_Click(object sender, EventArgs e)

{

    MyEntity ent = new MyEntity();

    ent.MyProperty1 = textBoxProp1.Text;

    ent.MyProperty2 = textBoxProp2.Text;

    ValidationResults r = Validation.Validate<MyEntity>(ent);       

    if (!r.IsValid)

    {

        DisplayValidationResults(r);

    }

    else {

        MessageBox.Show("ok");

    }

}

It's only left to provide the UI integration for the custom validator to assure averything's working right. I hope to be posting this in a second part soon.

16 April 2007

Workflow Foundation conference's material

The material (powerpoint presentation and code samples) of the Introduction To Workflow Foundation conference is now available for download.

20 March 2007

Sign up in the WF's conference @ MS Argentina

On Thursday the 12th (from 9 am to 1 pm) I will take part in the “Introduction to Windows Workflow Foundation” conference given at Microsoft Argentina, along with Diego Gonzalez (MVP) and Jorge Fioranelli.

Here is the conference abstract:

Between the new technologies included in the recently released .Net Framework 3.0, we found Windows Workflow Foundation, which consists on the most innovating tool set included in this new framework’s version. The possibility of extracting the workflow concept from the applications as a reusable and extensible element is an extremely innovating aspect in terms of application design. Tools are also included that let you visually edit workflows, enabling analysts and users without programming knowledge to extend applications with a minimum impact in the whole application.

The conference will consist on an introduction to the technology, showing its main characteristics, a demonstration of its more relevant advanced aspects, and will end with two examples of real projects where Windows Workflow Foundation has been used in combination with other technologies to solve common issues.

You can see the details and sign up here.

See you there!

17 March 2007

Environmental Overrides

February 2007 CTP of Enterprise Library 3.0 includes a very cool feature called "Environmental Overrides". This feature provides the capability of defining different environments in your application's configuration, and overriding some of the configuration settings in these environments. This is very useful in common scenarios, such as having different connection strings in development, testing and production. For a more detail explanation of how this works, read here, directly from its creator.

The tool sounded very promising to me, but pitifully, I couldn't make it work. I found the following two issues:

  1. When I generate the merged file for one environment (by clicking the "Save merged configuration" item of its context menu), the resulting file do not have the property's value overridden. This is an important problem for me, since it prevents the whole override feature to work. I reported this in more detail here, but the P&P people couldn't reproduce the bug.
  2. After reopening the app.config file, and loading one delta file for an environment, the settings for my overridden properties do not appear as expected. I see the "Don't Override Properties" option instead. I have also reported this with no luck here.
Is anyone having the same problem? Did anyone make it work?

12 March 2007

How-To: Implement a WCF Authorization Manager Using AzMan

This article intends to explain how to use AzMan to implement a custom authorization policy in WCF.

AzMan (Windows Authorizacion Manager) is a role-based application framework which provides runtime access validation methods, storage, and a UI to manage access control. The Authorization Manager runtime is separated from the authorization policy store, which may be stored in Active Directory, ADAM, or XML. AzMan is composed of two parts:

  1. Runtime: Provided by AZROLES.DLL, exposes a set of COM interfaces used by applications that employ role-based security.
  2. Administration UI: MMC snap-in that you can try out by running AZMAN.MSC or by adding the Authorization Manager snap-in to your MMC console of choice:

Follow these steps to use AzMan from within a custom authorization policy in your WCF Service:

1. Put AzMan to work with ADAM as the authorization policy store.

As I said before, the authorization policy store is independent from the authorization runtime. In this example I used ADAM as the policy store, but you can use an xml file as well.

1.1. Download and Install AzMan: AzMan comes with Windows Server 2003. For othe versions of windows, the Windows Server 2003 SP1 Administration ToolPack can be installed.

1.2. Download ADAM and create a new ADAM Instance (not available for Windows Vista)

1.3 Configure AzMan to use ADAM as the policy store

Steps 1.2 and 1.3 are explained in detail in steps 1 and 2 of this article, so you can follow the from there.

The ADAM instance can be administrated from the Adam ADSI Edit tool:

2. Ask for the user's permissions programmatically.

Once you have your role-based policy created in AzMan, is time to know how to ask for permissions programmatically.

2.1 In your .Net project add a reference to the Microsoft.Interop.Security.AzRoles assembly (found at %AzMan Download Dir%\Windows(R) 2000 Authorization Manager Runtime\PIA\1.2).

2.2 In order to connect to your AzMan application you can use the following lines of code:

AzAuthorizationStore store = new AzAuthorizationStore();
store.Initialize(0, ConfigurationManager.AppSettings["azManStore"], null);
IAzManApplication app = store.OpenApplication(
ConfigurationManager.AppSettings["azManAppName"], null);

The azManStore configuration entry is of the form:

"msldap://localhost:389/CN=AzManADAMStore,OU=SecNetPartition,O=SecNet,C=AR" for an ADAM repository, or
"msxml://c:/TestAuthStore.xml" for an xml file repository

2.3 To ask if a user has access to a given operation you need to istantiate an IAzClientContext from the user identity and then ask the context whether it has access to a given operation.

To obtain the client context from his user name:

IAzClientContext ctx = app.InitializeClientContextFromName(user, domain, null);

To obtain it from a System.Security.Principal.WindowsIdentity:

HandleRef handle = new HandleRef(this, identity.Token);
IAzClientContext ctx = app.InitializeClientContextFromToken(
(UInt64)handle.Handle, 0);

To ask for access to a given operation:

object[] operations = { (object)operationId };
object[] scopes = { (object)"" };
object[] results = (object[])context.AccessCheck(app.Name, (object)scopes, (object)operations, null, null, null, null, null);

If the result is 0 the access is granted.

Note that the query is made for the operation id, as it was entered in the AzMan operation definition. Usually you'll need a mapping between the operations ids and some friendly name.


3. Implement your a WCF custom Authorization Manager that relies on AzMan for authorization.

Now we have code access to AzMan to query for authorization, we want to integrate that to our WCF Service. We will implement a custom authorizationManager for that, since is the WCF natural extensibility point for authorization (although you can do it in a custom behavior also, the AuthorizationManager would be more accurate).

The custom AuthorizationManager must derive from System.ServiceModel.ServiceAuthorizationManager and override the CheckAccessCore method. For more information see How To: Create a Custom AuthorizationManager for a Service

In this example we will obtain the required action and the username from the operationContext and then use our AzMan utility class (AthorizationRepository) to ask whether the user has access to the given operation.

class MyAuthorizationManager : ServiceAuthorizationManager {

protected override bool CheckAccessCore(OperationContext operationContext) {

//Instanciate our AzMan utility class
AuthorizationRepository azMan = new AuthorizationRepository();

//Obtain the requested action from the context
string action = operationContext.RequestContext.RequestMessage.Headers.Action;

// Iterate through the various claimsets in the authorization context // to obtain the user name
foreach (ClaimSet cs in operationContext.ServiceSecurityContext.AuthorizationContext.ClaimSets) {

foreach (Claim c in cs.FindClaims(ClaimTypes.Name,
Rights.PossessProperty)) {

string userName = c.Resource.ToString();
//check access
if (azMan.HasAccess(userName, action)) {
return true;
}
}
}
return false;
}
}

Hope it result useful!

Some links:

AzMan
Developing Applications Using Windows Authorization Manager
Use Role-Based Security in Your Middle Tier .NET Apps with Authorization Manager

ADAM
Windows Server 2003 Active Directory Application Mode
How To: Use ADAM for Roles in ASP.NET 2.0

WCF Authorization
How To: Create a Custom AuthorizationManager for a Service (WCF)
How To: STS/Windows Authentication with ADAM/AD, Roles in AzMan with WCF
(using WCF behaviours)


11 March 2007

Documentation Generation in .Net 2.0

I found out that generating chm documentation from xml code comments in .Net 2.0 is not as easy as it was before. Thing is that NDoc has not been upgraded. Although it is available an NDoc2.0 alpha version, the product does not seem to be maintained.

Apparently, this is due to the throw of Sandcastle, the Microsoft's official documentation compiler (which is also included in Visual Studio's SDK Feb 2007). Though the documentation generation using this tool involves several steps, some of its users have already published scripts and tools that automate this task.

22 January 2007

Reflector's addins

I've been told of two addins for this great tool Reflector.

One is the File Disassembler addin, which you can use to generate code, in any language, from any assembly. This maybe useful for translating from one language to another, or to view the code in Visual Studio rather than in Reflector, but the truth is I haven't got the opportunity to need it yet.

The other addin, which I do use a lot, is the Code Metrics Addin. This one computes several code quality metrics of the assembly, such as the number of members of a class, the cyclomatic complexity, or the distance to the main sequence.

Since the link for downloading seems to be broken, I've upload it here.

Blogging tools

I've recently discover two handy tools for blogging. The first one is the Windows Live Writer. It is a little more friendly than the Blogger's editor, besides the advantage of allowing you to write offline. I have no problems in writing here to Blogger, despite of not being able to upload images.

The other tool I started using last week is the Google Reader. It is really cool, like all other google stuff. It has the drawback of you having to request the page, but you can access it from any computer.

More on WF: Getting Started

Continuing with the research on Workflow Foundation, here goes just a couple of things to get started with.

1- Quickly create your first sequence workflow

[See my previous post about the requirements for developing .Net framework 3 features.]

I am not going to put many details here, but to create your first workflow you need to select one of the workflow project templates in Visual Studio 2005. Just to start select the Sequential Workflow Console Application template. This generates a project with the references to the WF assemblies, the workflow itself and a test program.

By clicking on the workflow class the workflow is shown in the designer. Here is where you can drag activities from the toolbox. For example drag a CodeActivity. In the CodeActivity ExecuteCode property, type a method's name and press enter. VS will generate the method stub for you. Just write hello world to console there. Pressing the "view code" tab, the partial class with the workflow code (wfl properties, event_handlers, methods, etc) appears. You can see that the workflow inherits from SequentialWorkflowActivity.

So far we have the workflow defined with a set of activities. What we need now is to host the workflow and execute it. The generated program shows us how to do it:

using(WorkflowRuntime workflowRuntime = new WorkflowRuntime()) {

...

WorkflowInstance instance = workflowRuntime.CreateWorkflow(typeof(WorkflowConsoleApplication1.Workflow1));

instance.Start();

...

}

So, just press F5 and see the greeting message!

2- Get a feel of the Pre-build Activities

Some of the pre-build activities I have been experiencing with:

  • CallExternalMethod
  • Code
  • Delay
  • IfElse
  • Listen
  • Sequence
  • HandleExternalEvent

They are more or less self explained...I only want to mention one thing that may be a constraint in some circumstances:

The CallExternalMethod activity needs the following properties to execute:

  • InterfaceType
  • MethodName
  • Parameters

and the HandleExternalEvent similar properties:

  • InterfaceType
  • EventName
  • Parameters

In both cases the InterfaceType must be an Interface decorated with the ExternalDataExchange attribute, only this type of interfaces will be listed by the object browser. So the presence of that attribute is what I think may be a restriction as you can't use just any already built assembly.

3- Pass data to the WF:

There are two general approaches for receiving data into a workflow when it is started. They are Parameters and Events. With parameters, a list of parameter names and types are defined with the workflow. These parameter values are passed in by a host when it starts a new instance of the workflow type. With events, workflow authors add an activity that receives an event and data associated with the event. Events are generally specific to the host and custom activities that have been designed to handle the event.

The parameters can be passed in the CreateWorkflow method as shown here:

using(WorkflowRuntime workflowRuntime = new WorkflowRuntime()) {

...

Dictionary<string, object> parameters = new Dictionary<string, object>();
parameters.Add("FirstName", "Tom");
parameters.Add("LastName", "Sawyer");

WorkflowInstance instance = wr.CreateWorkflow(typeof(HelloWorldWorkflow.Workflow1), parameters);
instance.Start();

...

}

4- Make use of Conditions

A rule condition is a condition statement that is created in a dialog and stored as XML with the workflow. It can include predicates that compare workflow state and Boolean algebra combining multiple predicates. The conditions can be used in various activities including IfElse, While, ConditionedActivityGroup, and Replicator.

Take for example the IfElse activity. A condition can be set to one or both of its branches using the activity's properties. You can specify a CodeCondition or a DeclarativeCondition. In the first case you just enter the method's name. When you press enter the condition handler will be generated and shown in the code window. Put your logic in there, for instance:

public void If_Condition(object sender, ConditionalEventArgs e){

e.Result = this.reviewArgs.Review.Approved;

}

When using the DeclarativeCondition, you can use the Condition Editor to create it. You can access the workflow properties by intellisense.



16 January 2007

My turn in the blog-tag game!

As I’ve been tagged by my boyfriend, I suppose it’s my turn in this blogger’s game to play. So, here goes 5 things some people may don’t know about me:


  1. I went to live on my own a few months ago, to a very cute apartment in Almagro, 5 blocks from my parents. It can’t actually be said a live “alone” since I have this eternal, and of course very welcome and lovely visit, my boyfriend.

  2. I have a degree in Electronic Engineer from the University of Buenos Aires, but I’ve never worked as such. I have always worked as a software developer, nowadays in a great software company: Lagash Systems.

  3. I have always like Maths. I kind of have it in the blood since both my parents are mathematicians. I’ve always teach math, first giving particular lessons and since many years now at the university, where I still teach “Algebra II” and used to teach “Probability and Statistics” too.

  4. When I was young I studied music for many years (since I was 6 till 15) at the National Conservatory. I played piano and flout. Unfortunately I have a very bad memory and can’t remember a single piece of music. But I can still play if I’m in front of the sheet. I play mostly classic, despite for some Queen songs I learned when I was a teen and a great fan of them.

  5. In my free time? I like to walk, dance, and go biking a lot. I try to go by feet everywhere whenever it is possible. I don’t like to stay much inside, I prefer to take some air. I really enjoy going anywhere with my boyfriend, going to the country house on Sundays with the family and hanging out with my friends.


Now it's time to tag another 5 people: RodolfoF, Zaiden, PabloC , Cyn and Pede.