Connecting to a Workflow Service from LightSwitch Part 2

Overview

The second part of this topic discusses how to deploy the Workflow service that was implemented in Part 1, how to create a proxy used in either a console application or test project and how to create a proxy used by a LightSwitch application.

Deploy the Workflow service

For the following task, start Visual Studio 2010 and a Visual Studio command prompt window with administrator privileges. You need sufficient rights to publish to IIS as well as run other tasks, such as iisreset, you may need during debugging.

I am running on Windows 7 with IIS installed on the same machine. If you’re running on Windows Server 2008 or deploying to IIS running on a different machine, your steps may be slightly different, yet have enough similarity to follow along here.

In the VS 2010 command prompt window, navigate to the inetpub\wwwroot directory and create a folder to publish the workflow service. I named my folder WFServiceOrderProc

Next, go to the VS 2010 solution and right mouse click on the workflow service project, ServiceLibrary. Select Publish… in the pop up context menu to display the Publish Web dialog.:

Select File System as the publish method in the Publish Web dialog. Specify the target folder you created in the VS 2010 command prompt window.

clip_image002

Click Publish to deploy the workflow service to IIS.

Next, start IIS Manager. One way to quickly start IIS Manager is by entering INETMGR in the search programs and files textbox from start programs.

In IIS Manager, change the WFServiceOrderProc from a folder to a web application.

clip_image003

Next, in the IIS category, double click the Directory Browsing icon to display the Directory Browsing properties. In the right panel, click enable to enable directory browsing.

clip_image004

Next, right mouse click the WFServiceProc -> Manage Application -> Browse

clip_image005

A browser similar to this should start:

clip_image006

Click the OrderProcessing.xamlx link should display this:

clip_image008

Copy and paste to a temporary file the line starting with SVCUTIL.EXE. Change the machine name LAPTOP1 (my machine) to local host.

svcutil.exe http://localhost/WFServiceOrderProc/OrderProcessing.xamlx?wsdl

With these steps completed, you have the workflow service deployed and verified IIS can run it. The next step is creating a client project to run and test the workflow service.

Create a Test Project and Proxy

Return to Visual Studio and create a new project using the Test template.

clip_image010

In the Visual Studio command prompt, navigate to the Test project folder and run the SVCUTIL command.

clip_image012

The SVCUTIL command will connect to the workflow service, read the metadata, and create a proxy called OrderProcessing.cs.

Add the OrderProcessing.cs file to the Test project.

Rename the file UnitTest1.cs to TestCalcShippingWorkFlow.cs

Add the following assembly references to the test project:

· System.Runtime.Serialization

· System.Runtime.ServiceModel

Next implement a constructor to create the proxy and implement workflow service tests.

Below are the constructor and one of the test implementations. You can find all the tests in the zip file that’s part of this posting.

clip_image014

 

Create a Proxy for LightSwitch

Because LightSwitch is a Silverlight application, the proxy created above will not work in a LightSwitch solution. You need to implement the proxy using async methods and use different assembly references for a LightSwitch solutions.

Creating this workflow service proxy is very similar to creating the proxy to a WCF service I described in an earlier blog post. To ensure we’re on the same page, I’ll explain the steps again here.

Open a light switch solution. I called mine OrderHeaderTest. At this point, select Attach to External Database and connect to the AdventureWorks database. Use the wizard to connect the SalesOrderHeaders table. It’s not important at this point to do more in the LightSwitch project. I’ll describe more about the screens and code behind in the next post.

Add a new project to the OrderHeaderTest solution using the Silverlight Class library template. Rename the Class1.cs file to OrderProcessing.cs.

In the VS 2010 command prompt, navigate to the folder containing the OrderProcessLib solution and use the SLsvcutil.exe to create a Silverlight proxy. On my machine, the SLsvcutil utility is in this path:

“c:\Program files (x86)\Microsoft SDKs\Silverlight\v4.0\Tools\SLsvcutil.exe” http://localhost/WFServiceOrderProc/OrderProcessing.xamlx?wsdl

clip_image016

Add the generated proxy, OrderProcessing.cs, to your OrderProcessLib project.

Implement the LightSwitch Proxy

The class constructor creates the proxy, an OrderProcessingRequest and OrderProcessingResponse objects. (Lines 20 – 29)

The constructor initializes a AutoResetEvent object used to signal completion of the async callback method, _proxy_ProcessOrderCompleted(). (Line 24)

Finally the constructor wires up the async callback method. (Line 31)

clip_image018

The proxy’s method to invoke the workflow is straightforward. It takes three parameters which it copies to the OrderProcessingRequest object. (Lines 42 – 44). In then evokes an async call to the workflow service (line 46) and waits for the completion of the callback (line 48). On completion, the proxy returns the value of the calculated shipping charge (line 50).

clip_image020

That completes the deployment of the workflow service, testing the service, and implementing the proxy for the LightSwitch application.

The next blog post will describe using the workflow service from the LightSwitch project.

 

Posted in LightSwitch | Leave a comment

How to Interface LightSwitch to a Windows Workflow Part 1

Overview

In my last blog posts  I described how to connect to a generic WCF service from LightSwitch. In this blog post I will build on the previous postings to describe how to connect to a Workflow (WF) Service.

Like my earlier posts describing how to interface to a WCF service from LightSwitch, this will also be a multiple part posting.

This first part will describe how to create a simple WF service.  There is a lot of configuration to describe, for even a simple WF service.   So I want to limit this first post to just focus on getting the WF service ready for deployment and testing.

The second post will describe how to deploy the WF service, create a proxy to the service, and implement a simple Console application to test the service.

The third post will describe the code to write in LightSwitch to use the WF service.

Why Windows Workflow?

I think Windows Workflow adds value to a business application. You can use a workflow to define and implement business logic for a variety of business related problems such as order processing, document management and approval, defining how to flow data through a customer contact process.

What I like about workflow is it allows you to decouple your business logic from your application.

One advantage of decoupling is you can make changes in your workflow logic without the necessity of updating your application. As long as the interfaces to your workflow remain consistent, you can make internal changes to your workflow without needing to recompile, retest, and redeploy your business application.

Another advantage of using WF is you can have a library of WF implementations used by different applications in your organization. You may have ASP.NET applications currently using a WF library. If you can reuse the business logic in your WF in another application, that’s less code you need to write and test as you migrate to another application platform such as LightSwitch.

Technology changes, and LightSwitch will be version 1.0 when it goes RTM. Will the interfaces and internal implementations change for V2.0? Will some other product based on different tooling replace what you do in LightSwitch? By decoupling business logic, you can reduce the risk of future work.

Finally, a current issue with LightSwitch it is difficult to perform automated testing. Business logic tends to be hard to get correct due to multiple conditions and paths which need verified. It tends to change based on business needs. Business logic (rules / workflow) often needs persistence, tracking, and bookmarking to resume the logic.

Putting that logic into LightSwitch becomes problematic. You can build the business logic into a DLL and test the library via automated tests. But likely, that implementation will have dependencies which preclude usage in other application environments. WF is designed to solve these kinds of problems for business logic. And testing workflows in WF is arguably easier than testing equivalent ‘home grown’ logic hosted within LightSwitch.

Defining the Workflow

At first I thought it possible to create a workflow called from LightSwitch by creating a simple WF library. I quickly found that can’t work. The problem is LightSwitch, being a Silverlight based application, only allows you to run a subset of the .NET 4.0 assemblies. I found it necessary to create a Workflow Service and call that service from LightSwitch—similar to calling a vanilla WCF service.

To start off, I wanted a very simple WF example. In future posts I plan to create a more complex workflow. But for this first example, I want something easy to understand which demonstrates how to wire up a WF service and use it from LightSwitch without getting hung up in workflow complexities.

I’ve been reading Bruce Bukovics book, Pro WF Windows Workflow in .NET 4, published by Apress (ISBN 978-1-4302-2721-2) to learn more about WF.

For this example, I’m using an example workflow described his book which calculates shipping charges on an order. Since I’ve using the AdventureWorks database which contains a OrderHeader table, this is a reasonable starting point.

I’ll call the workflow CalculateShipping. The business rules are as follows:

If the shipping method is ‘normal’ is specified, the following rules apply:

  • If the total order exceeds 75.00, the calculated shipping is 0. (free shipping).
  • Else the calculated shipping is the weight * 1.95.

If the shipping method is ‘express’, the following rules apply:

  • There is always a shipping charge for an express order
  • The shipping is calculated as weight * 3.5

There is a minimum shipping charge:

  • If the shipping charge is > 0 and less than 12.5, the shipping charge is 12.50.

Data provided to the workflow to calculate the shipping charge comes from the AdventureWorks OrderHeader table. OrderHeader.ShipMethod contains the data for the Shipping Method. In the database, the table is populated with ‘CARGO TRANSPORT 5’. For expediency, I implemented the workflow to process ‘CARGO TRANSPORT 4’ as ‘normal’ and ‘CARGO TRANSPORT 5’ as ‘express’

There is no Weight field in OrderHeader, so for expediency in demonstration, I’m using the data in the Freight column as ‘weight’

OrderHeader.TotalDue provides the data for “total order”

Implementing the CalculateShipping Workflow

The first step to implementing the workflow is to create a Visual Studio 2010 Workflow Services project and call it ServiceLibrary.

clip_image002

First I delete the ReceiveRequest and SendResponse activities in the designer.

clip_image003

Next, under the Messaging category in the Toolbox, I drag the ReceiveAndSendReply activity onto the design service, inside the Sequential Service activity:

clip_image004

Next I rename the xamlx file from Service1.xamlx to OrderProcessing.xamlx

Next I add three class files to the project:

1. OrderProcessingRequest.cs

2. OrderProcessingResponse.cs

3. CalcShipping.cs

This is the implementation for OrderProcessingRequest:

clip_image005

This is the implementation for OrderProcessingResponse:

clip_image006

As you can see, both of these classes are simple containers.

CalculateShipping implements the business rules described earlier for calculating the shipping rate.

The implementation for the CalculateShipping activity is:

clip_image007

Key points of the implementation:

1. I want CalculateShipping to be a custom code activity which returns a decimal value of the calculated shipping rate. You can do this by deriving the class from CodeActivity<decimal> as seen in Line 22 of the source.

2. This custom activity has three input parameters: Weight, OrderTotal, and ShipVia (which is the Shipping Method). These parameters are defined as InArgument<decimal> as shown in lines 24 – 26 of the source.

3. The work for this custom activity is done in the overridden Execute() method, starting at line 33.

4. To get the value of the passed in argument in a workflow, you need to use the CodeActivityContext passed as a parameter to the Execute() method. For example, to get the value of the ShipVia argument, you use ShipVia.Get(context) as seen in line 39.

5. The implementation of the business rules is straight forward– a simple switch statement, and some calculations based on the Shipping Method, Weight, and OrderTotal.

6. When the CalculateShipping activity ends, it returns the calculated shipping amount that’s contained in the result variable, at line 67.

7. On line 37, the commented Debugger.Break()is one way to easily debug the service when you deploy it to IIS. When you uncomment this line and deploy the WF service to IIS, a dialog prompting you to attach debugger to the IIS thread pops up when the client executes the workflow.

With these classes defined, you should get a clean compile.

Having built the CalculateShipping custom activity built as part of the project, double click the xamlx file again to view the designer and open the Toolbox. You should see the CalculateShipping now included in the ServiceLibrary category of the Toolbox. Drag and drop the CalculateShipping activity onto the designer followed by dragging and dropping an Assign activity, located in the Primitives category of the toolbox.

Your workflow should appear similar to the following:

clip_image009

Now that you have the classes built and the activities laid out in the designer, you need to do more configuration!

In the lower left of the designer, click the Variables tab. You need to define variables which the workflow uses as it runs the activities contained in the Sequence activity. Define a Request, a Response, and a CalculatedShipValue variables.

The Request variable is a OrderProcessingRequest type. It contains the data received from the client, in the Receive activity.

The Response variable is a OrderProcessingResponse type. It contains the data sent back to the client by the SendReplyToReceive activity

The CalculatedShipValue variable is a decimal type. It holds the calculated result from the CalculateShipping custom activity.

The Assign activity added after the CalculateShipping custom activity assigns the value in CalculatedShipValue variable to the Response.CalculatedShipping.

After you have defined your workflow variables, your designer should look similar to the following:

clip_image011

Some key points to note when you’re defining the variables:

· The Response variable needs to be New’d from the OrderProcessingResponse.

· The decimal type- you can browse to mscorlib [4.0.0.0], then System, then scroll down to Decimal. If there’s a faster / better way of doing this, let me know. It took me a while to figure that out and it was a PITA to get it defined as a decimal type the first time around.

Ok, now that you have the variables defined for the workflow activities, you have to configure the activities.

In the designer, click on the outer most activity. In the property window, set the DisplayName property to Sequence. (this is just so we’re on the same page if you’re configuring the service as in the attached archive to this post.)

Next, click on the Receive activity.

Set the properties as follows:

clip_image013

Next, click the Content text box of the Receive activity to display the Content Definition dialog. In the Message Data field, enter the name of the variable containing the data received from the client—Request.

clip_image015

Next, click the CalculateShipping custom activity. The property dialog contains the input and output variables of the custom activity. You need to set the input variables to the value of the data contained in Request. And set the Result (the output variable for this activity) to the variable CalculatedShipValue:

clip_image017

In the screen shot above, when you click the button with three dots, the designer will pop up a dialog like the following where you can enter your expression. Note that the dialog does indicate the type, such as Decimal.

clip_image018

Next, click the Assign activity. The Assign activity is where you copy data from the CalculatedShipValue variable set by the workflow to the Response.CalculatedShipping variable.

clip_image020

Finally, click the SendReplyToReceive activity and configure the Request property to get its data from the Receive variable.

clip_image022

And click the text box next to Content to display the Content Definition dialog. Set the Message Data to use the Response variable:

clip_image024

Next, open the Web.Config file and verify it appears as follows:

clip_image025

The default setting for serviceDebug is false. I changed it to true in my configuration file so that the client would receive fault diagnostic data during testing.

One more configuration: close the designer and open it by double clicking the xamlx file. In the property window, make sure you have the ConfigurationName and Name properties set correctly:

clip_image026

That completes the implementation and configuration of the CalculateShipping WF service.

The next blog post will describe how to deploy this service, create a test Console application and generate a proxy for use by the Console test application.

Once you have the WF service deployed and tested, you’ll be ready to start using it from LightSwitch!

Posted in LightSwitch | 1 Comment

How to Connect to a WCF service from LightSwitch- Part Two

In part one of this topic, I discussed how to implement a WCF service and create a proxy to the WCF service which you can use in a LightSwitch application.

In this post, I’ll show you how to use that proxy and make updates to the product table within LightSwitch.

In my exploration to learn about LightSwitch, I’ve been using the AdventureWorks Light database.

For this example, I create a new table called SimpleProduct based from the the SalesLT.Product table.

The schema for the SimpleProduct table is:

clip_image001

I used the following script to populate the SimpleProduct table:

clip_image002

I’ll assume that you already know how to create a LightSwitch application, connect to an external database, connect to the SimpleProduct table, and create a search and details screen from the SimpleProduct entity.

 

In my LightSwitch project I created two screens and called them SearchSimpleProduct and SimpleProductDetail.

Show the SearchSimpleProduct screen in the designer.

In the Screen Command Bar, add a new button and call it UpdateAllProductPrices:

clip_image004

 

Right mouse click UpdateAllProductPrices and click Edit Execute Code in the context menu:

clip_image005

 

In Solution Explorer, change from Logical View to File View:

clip_image006

 

Next, navigate to the Client node in the solution explorer and add a reference to the Product.Wcf.LSProductProxy assembly built in part one of this topic.

clip_image007

 

In the code file for the button execute, add the following using statement:

clip_image008

 

Next, add the following code to Button_Execute()

clip_image010

In the code example above, lines 14 creates an instance to the proxy which handles the asynchronous calls to the WCF service. Line 15 requests the collection of product price updates.

Recall from part one of this topic, the product price data is contained in a ProductPriceInfo object and GetAllProductPriceUpdate returns a collection of ProductPriceInfo objects.

Also recall, the WCF service implementation is hard coded, for demo purposes, to return three ProductPriceInfo items, for products FR-R92B-58, HL-U509, and SO-B909-M

Line 17 – 15 iterate through the collection of returned ProductPriceInfo objects and updates the Product table.

Line 18 queries the SimpleProduct entity using the ProductNumber.

If the product is found, the returned product entity’s ListPrice and StandardCost are updated with the data contained in the ProductPriceInfo item. Because the ProductPriceInfo item’s data is of type double, and the entity uses a type decimal (money), the code performs a conversion to a decimal type.

(I intentionally defined the data from the service as a double instead of a decimal, in the spirit of using a legacy WCF service in which you may not have control over the data types the service gives you. This demonstrates a simple case where you need to do a data conversion in the code before saving the data in the entity.)

Line 23 writes the updated product entity to the database.

Before running the update, the StandardCost and ListPrice are shown here from SQL Management Studio:

clip_image012

 

After

clip_image013

 

Or, as viewed from the LightSwitch application, the Product prices before clicking UpdateAllProductPrices button and after clicking the button.

clip_image015

After

clip_image017

Posted in LightSwitch | 7 Comments

How to Connect to a WCF service from LightSwitch- Part One

Recently a question Can LS be used as a client to a Web Service? was asked on the LightSwitch forum

The question got me thinking about how does one connect to a legacy WCF in a LightSwitch application? Many shops have legacy web services which they may want to use from LightSwitch application.

Because I’ve implemented WCF solutions in the past, I thought connecting to a WCF service from LightSwitch would be a piece of cake. As it turned out, it became a learning experience as I needed to solve a few problems I hadn’t encountered before. Because of the amount of content, I plan to make two posts to explain how I solved the problem and some of the issues I encountered.

The scenario is a business needs to get current pricing information for a product. The user wants to have product price information updated from a LightSwitch screen when user clicks a button.   On the button click, the screen’s code connects to a web service to get current product pricing and updates the product table.

In this blog post I’ll discuss creating the WCF service and a proxy to that service which you can use in LightSwitch.

In the next blog post, I’ll show you how to connect to the WCF service from a LightSwitch screen and update the product table.

 

Creating the WCF Service

Because I’ll be creating a WCF service and deploying the service to IIS on my local development box, I first start Visual Studio 2010 with administration rights.

Next I create a blank solution called Product.Wcf

clip_image002

When creating a WCF solution, I prefer to define one assembly for the Interface file so the service and client code can use the same interface definition. For this demo I’ll simplify the solution and put the interface and the service code into the same project.

Add a WCF Service Library project to the Product.Wcf solution. Call it Product.Wcf.Service:

clip_image004

Delete the App.config, IService1.cs and Service1.cs files which Visual Studio added to the project;

clip_image005

Add two files to the project: IProductService.cs and ProductService.cs.

I want two methods for this WCF demo- GetProductPriceUpdate() and GetAllProductPriceUpdate().

I want the GetProductPriceUpdate() to return price information using a passed in product identifier.

I want GetAllProductPriceUpdate() to return a collection of products with price updates.

I want the returned data contained in an object called ProductPriceInfo. ProductPriceInfo holds the product number and the new list price and standard price for the product.

With these requirements in mind, the IProductsService.cs file looks like this:

clip_image007

For the service implementation, I’ll simulate reading results from a back end database by just returning a fixed result set. The simple service implementation becomes:

clip_image009

GetProductPriceUpdate returns a price update for product “FR-R928-58”, otherwise it returns nothing.

GetAllProductPriceUdpate() returns price updates for three products.

With the WCF service implementation defined, I want to deploy the WCF service to my development machine’s IIS server.

First create new project of type WCF Service Application and call it Product.Wcf.WEB

clip_image011

Delete the IService1.cs and Servcie1.svc.cs files Visual Studio includes in the project and rename Service1.svc to ProductService.svc

clip_image012

Next, add a reference to the Product.Wcf.Service assembly from the Product.Wcf.Service project.

clip_image013

Next I open the ProductService.svc file and change the Service tag which reference the fully qualified name of the service code implementation:

clip_image014

 

 

Publish the WCF Service

The next step is to publish the web site. On my development machine, I entered the selections highlighted below:

clip_image001

Finally, start IIS manger to configure the site and test it.

When you first start IIS manager after publishing, you should see a folder labeled ProductService under the Default Web Site. Right click this folder and click the Convert to Application in the pop up context menu. The icon should change from a folder to a Site icon:

clip_image002[6]

Next, configure the site to enable directory browsing:

clip_image004[5]

With the ProductService site selected in the left pane, double click Directory Browsing.

Then click Enable in the Directory Browsing dialog:

clip_image006

Next click Browse to start an instance of Internet Explorer:

clip_image008

You should see the following in Internet Explorer.

clip_image009[5]

Assuming all is configured correctly, you should see the following when you click ProductService.svc:

clip_image011

Write down the line circled above, you’ll need it in a moment.

 

 

Test the WCF Service

At this point, your web service is deployed and running. It’s always a good practice to test the code works, so let’s next create a simple console application to test the WCF service.

Add a new project to your solution- create a Console Application project and call it Product.WcfConsoleTest

clip_image002[8]

Now, start a Visual Studio 2010 Tools command prompt. If you haven’t done this before, navigate to:

Start-> All Program -> Microsoft Visual Studio 2010 -> Visual Studio Tools -> Visual Studio Command Prompt (2010)

In the command prompt, navigate to the directory of your ConsoleTest project.

Then run the command you saw above in the Internet Explorer window.

clip_image004

Svcutil generates a file ProductWcfService.cs which contains the proxy code to connect to your WCF service. Add the ProductWcfService.cs file to your ConsoleTest project:

clip_image005[4]

Next, add the System.ServiceModel and System.Runtime.Serialization assemblies to your ConsoleTest project references:

clip_image006

Next, write some code to test the WCF service in Program.cs:

clip_image008

This simple test creates an instance of the ProductService proxy, using the address of the WCF service which you saw in Internet Explorer above. The test then verifies the GetProductPrice returns a null ProductPriceInfo for a product other than “FR-R92B-58”. It then checks that GetAllProductProiceUpdate() returns three ProductPriceInfo, as implemented in our service.

After running this test, I thought, “Great! Now I can use the generated ProductWcfService.cs proxy code in my LightSwitch application”.

Well, I found out this was a very wrong assumption. First, when I tried to add a reference to an assembly containing this proxy to a LightSwitch project, Visual Studio showed the reference added, then in a few seconds removed it. Uh?!? I thought.

 

 

How to create a proxy you can use in LightSwitch

I fiddled around and soon realized the generated proxy code I used in the ConsoleTest project (generated by SVCUTIL.exe) cannot be used in a LightSwitch application, which is in reality a Silverlight application. I also found Silverlight requires a different version of the ServiceModel and Runtime.Serialization assemblies. And Silverlight requires the proxy to have asynchronous interfaces on the method calls. SVCUTIL creates synchronous method calls which won’t work in the LightSwitch environment.

After debugging in LightSwitch and exploring deeper, I found several pages which helped me come up with a solution. Here are references to pages which helped me and which you may want to read and drill deeper:

Silverlight and WCF Feature Comparison

Sharing Silverlight Assemblies with .NET Apps

Using SLsvcutil.exe to Access a Service

Using WCF Async pattern with Silverlight 3, Russell East’s blog

Silverlight 4 Synchronous WCF Service Calls, Benjamin Day’s blog

I discovered one way to create a usable proxy is by using the utility SLsvcutil.exe. I also learned I needed to call the WCF methods asynchronously. Because I want to hide the complexity of asynchronous calls from the LightSwitch code, I decided to write a façade class. A proxy to a proxy you might say Smile

I also learned you should use a Silverlight Class library instead of a regular .NET Class library project in order to pick up references to the correct versions of the ServiceModel and Runtime.Serialization assemblies.

With the above in mind, add another project to the Product.Wcf solution. The project type is a Silverlight Class Library.  Call the new project Product.Wcf.LSProductProxy:

clip_image002[10]

Delete file Class.cs from the Product.Wcf.LSProductProxy project.

Add references to the ServiceModel and Runtime.Serialization assemblies. Notice the version numbers of these assemblies are 2.0.5.0. A little later as you’re working in the LightSwitch project, you’ll notice these are the same versions used by LightSwitch.

clip_image004[5]

Next, in the Visual Studio 2010 command prompt, navigate to the directory of your Product.Wcf.LSProductProxy project. Run the SLSvcUtil.exe utility to generate a proxy usable in a Silverlight environment. On my machine, the SLSvcUtil.exe is located here:

c:\Program files (x86)\Microsoft SDKs\Silverlight\v4.0\Tools\

clip_image006[6]

Add the generated file, ProductWcfService.cs, containing the proxy to the WCF service to your project.

Add another file called LSProxy.cs to your project. LSProxy will implement the calls to the WCF service and encapsulate the complexities of managing asynchronous method calls.

Here is the implementation of LSProxy:

clip_image008[5]

In lines 27 and 28, the constructor wires up the event handlers for the asynchronous calls:

clip_image010

In line 22 and 23, the constructor initializes an AutoResetEvent for each asynchronous method:

clip_image011[5]

The following is what happens when the LightSwitch application makes a WCF service call. For example, when the LightSwitch code calls LSProxy.GetProductPriceUpdate the following code executes:

clip_image013

The LightSwitch code calls LSProxy.GetProductPriceUpdate(string product). This method calls the WCF asynchronous method GetProductPriceUpdateSAsync(product) implemented in the generated code file, ProductWcfService.cs. A call to the WCF service is initiated and control returns immediately to LSProxy.GetProductPriceUpdate. The thread which makes the call to GetProductUpdateAsync blocks waiting for a signal from the AutoResetEvent (_autoResetEventGetProductPriceUpdate.WaitOne).

The thread executing LSProxy.GetProductPriceUdpate is the UI thread that is running the LightSwitch screen. Note that as this thread is blocked, this can block the LightSwitch application. Handling this problem may be as simple as providing a timer in the WaitOne call, or some more complex solution such as showing a pop up display with animation which the user can cancel may be needed for very long running processes—a topic for a future blog post.

When the WCF service returns data to the proxy, the data comes in on a different threat of execution and runs _proxy_GetProductPriceUpdateCompleted. This method copies the received data into the private member variable and unblocks the thread which called GetProductPriceUpdate.

Being unblocked, the main thread gets the data from the member variable and returns the data to the LightSwitch application.

 

Summary

In this post I demonstrated how to create a simple WCF service, deploy it, test it from a console application, and create a proxy to the service which you can use in a LightSwitch application.

In my next post, I’ll show how to use the proxy to make WCF service calls and update data within LightSwitch.

 

Project source files ProjectWcfSolution.zip

Posted in LightSwitch | 7 Comments

How to Initialize an Entity’s Property in LightSwitch

While using Visual Studio LightSwitch with an external database, I came across a minor issue when creating a new entity.

I’m using the AdventureWorks Light database in my exploration. Most of the tables contain a field called rowguid.

The problem I encountered is how to initialize a property of type Guid when adding a new record.

For example, when you create a Customer entity using the SalesLT.Customer table in the AdventureWorks Light database, the Customer entity appears in the designer as follows:

clip_image001

I added a SearchCustomer screen and added an Add… button in the Command Bar.

When I run the app and click Add… button in the Customer screen, LightSwitch creates an empty GUID in the rowguid field:

clip_image002

The behavior I want is to automatically create a new Guid.

As a side bar conversation, you can argue the need to display this field. I believe in most cases you would want this field hidden. Only in a few cases, such as some type of management screen, would you want the Guid which identifies this row uniquely to be shown.

In any case, I don’t want to require the user to enter data in this field or for the field to be initialized to 0 for each new record.

Auto generating the Guid is accomplished by adding code in the entity’s Created method.

The first step is to have LightSwitch generate code that’s called when it creates a new Customer entity. Open the Customer Entity in the designer. Click Write Code in the main menu, then click Customer_Created in the drop down menu.

clip_image004

Next, add code to initialize the Customer’s rowguid property.

clip_image005

Now when you add a new customer record, the rowguid is initialized:

clip_image006

Posted in LightSwitch | 5 Comments

Extending a Legacy Application by Associating Local Data with External Data

 

Overview

This weekend I was reading Robert Green’s recent post Using Both Remote and Local Data in a LightSwitch Application.

The example of connecting to an existing table and developing an application which uses its own tables intrigued me.

In this post I’ll discuss how I solved the problem a little differently than Robert did and the problems I encountered.

I see potential of using this idea as a way to write an application to add onto functionality of an existing application. There are many users of business applications like Microsoft Dynamics SL and Business Portal who may use this technique as a way to quickly generate an application that adds to out of the box behavior.

Some users may want their existing application customized, using the customization features provided in Dynamics SL. But they may discover the customization work is much more expensive in time resources than using a tool like LightSwitch to create an add-on application to provide an enhancement.

Steps

I started stepping through Robert’s post to learn more and test the concept.

In my exploration, I used a scenario similar to Robert’s example of extending a Customer table.

In my contrived example, I want new customer attributes. In some applications, like Microsoft Dynamics SL, extra fields are added to a table with the intention of allowing application customization by use the extension fields.  But often, an application doesn’t have additional fields for customization, or the fields are already in use from early customization work. 

How well will this idea work in having an application create its own table and appear to seamlessly bind the tables together into a consistent user view?

Some of this post is a duplication of what Robert discussed and as well as shown in the How Do I? videos. Hopefully some readers will find, where there’s overlap, that the content here is useful in the context of seeing the problem solved a little differently.

In this scenario, I’m adding attributes of gender, age, and ethnicity to the customer table. As I said, it’s contrived, but it demonstrates what I want to show in this post.

I started by creating a simple environment.

First I opened SQL Server Management Studio and created a new database, called CustExtTest (Customer Extension Test)

Then I created a single table Customer using the following script:

clip_image001

Then, in the Object Explorer pane in SQL Management Studio, I right mouse clicked on the Customer table and selected the context menu item Edit top 200 rows.

I entered the following three rows into the Customer table:

clip_image003

With the external database setup, I started Visual Studio, created a LS project, and connected to the external database.

clip_image005

clip_image007

Next I right mouse clicked on the Data Sources folder in the project and selected Add a Table from the pop context menu. I added a table called CustomerAttributes and added three fields to the table– Gender, Age, and Ethnicity.

If you’re following along in Visual Studio, your project should appear similar to this:

clip_image009

Next I added a relationship between the Customer table and the CustomerAttributes table, similar to Robert’s example.

Then I added the CustomerSearch and CustomerDetails screens.

clip_image011

Like Robert explained in his post, I changed the Model Window Picker to a Vertical Stack. Notice that LightSwitch adds text boxes for the fields in CustomerAttributes.

clip_image012

The ViewModel, the left hand pane of my CustomerDetail’s screen, looks like this:

clip_image013

Notice the link between the Customer.ID and the CustomerAttributes.ID.

I hit F5 to run the application. Then clicked SearchCustomer and selected a customer in the results grid. The CustomerDetail screen appears with the three fields from CustomerAttributes disabled (read only):

clip_image015

Exactly the expected behavior, as described in Robert’s post.

Ok, great!

So far this has been pretty much a duplication of what Robert blogged and what you find in the How Do I? videos.

Divergence

This is where we start to diverge from Robert’s post.

As Robert described, in order to enable these fields , you have to add a new object ( the CustomerAttributes object) to a Customer object.

Since I’m using C#, the code looks a little different than Robert’s example in the Customer_Created method.

The first time I entered the C# code in Customer_Created method, Visual Studio indicated, via the red highlighting, it had no reference to the CustomerAttributes object:

clip_image017

Whaaat??@!?  Surprised smile

CTRL-SHIFT-B to build produced a boat load of errors:

clip_image019

Ok, expected, but .. WHAAT?@@@???  Disappointed smile

I did some exploration but couldn’t find a solution to this problem of unknown references.

It got to be meal time,, so I closed the solution, left my office, and grabbed a bite.

Returning later feeling refreshed, I opened the solution, and well, well, well, well…. Check this out: Open-mouthed smile

clip_image021

On reopening Visual Studio, the with no code changes, now Visual Studio indicates no missing references.

I did a build, but still got errors.

WHAT!*#(??!?   Angry smile

The build error indicated a namespace error with CustomerAttributes.

“Well, isn’t that special”, I said to myself, because Visual Studio didn’t indicate an error condition until the build.

Ok, Whatever…

I changed the code to the following and got a clean build:  Open-mouthed smileOpen-mouthed smile

clip_image022 

“Ok”, I mumble under my breadth, “This IS a beta release.”

(as well, as mumbling a few times, “Bite me”)

Don’t forget LS is a beta release. Assuredly you will be reminded if you ever forget it.

As a former coworker use to say when we worked with early C++ compilers, “Isn’t bleeding edge fun?

So I’m happy, and progress to another step Robert discussed in his post—how to handle an existing customer record.

Robert posted the following code fragment (Without my annotations in his code J )

clip_image024

I don’t know if in my naiveté I overlooked a step in Robert’s blog, but I could not figure out how to get a CustomerQuery object .

What I did find is a DataWorkwspace object.

I couldn’t find documentation about a DataWorkspace object. Perhaps I’m not looking in the right places? (or should I chalk it up to this IS a beta product and the documentation is not fully cooked.)

I found some discussion about Data workspaces here, here, and here.

Enough to give me a better understanding than what Intellisense provides Smile with tongue out

The following is the code I came up with:

clip_image026

In step 1, the customer entities read from the database are obtained.

Step 2 gets the customer entity selected in grid of the SearchCustomer screen.

Step 3 constructs a new CustomerAttributes object and assigns it to the selected customer. It also sets the CustomerAttributes.Customer property to the selected customer.

Just for exploration, I left the code in the bottom of the screen shot as an example of iterating the customer collection.

So that’s it. The implementation is not exactly as Robert showed in his posting, but it appears to get the job done.

I welcome,- nay, encourage—feedback if you see this implementation is problematic.

If someone can point out what I missed in not seeing a CustomerQuery as Robert described in his blog, my thanks in advance.

Posted in LightSwitch | 2 Comments

Why I Believe Visual Studio LightSwitch will be a Win

In my career, I’ve worked with several Microsoft products which failed.   Sometimes you have a sense early on that a product will be a Fail.   Other times the product’s future initially looks promising but due to development delays and changing market conditions the product becomes a Fail.

I’ve been checking out Visual Studio LightSwitch the past couple months and believe it has a bright future.

This article discusses an earlier Microsoft product which LightSwitch takes a lot of ideas from and why I think Microsoft is getting it right this time.

Awareness

When I first read about LightSwitch, it caught my attention because of my experience in developing business applications and working with business application frameworks. Its goal of giving the user rapid application development, the ability to connect to multiple data sources and its support to multiple deployment environments differentiate it from other tools I’ve worked with in the past.

What really piqued my interest is seeing familiar faces and names on the Channel 9 videos and in the LightSwitch Developer’s forum. Some of these folks have been in the business application development ecosystem for a couple decades. They bring a wide and deep experience of knowing what works, and more importantly, knowing what fails.

First Steps

I downloaded and explored the example applications.

I listened to the How Do I videos and read through the Q & A on the LightSwitch Developer Center Forum.

I read some great blog postings by Michael Washington showing the ease of developing a Student Information System application using LightSwitch.

Forming an Opinion

I haven’t seen a development tool quite like LightSwitch.

Developers often speak of code smells in discussing code that doesn’t look right, which hint at deeper problems in the design of the code.

Well, I also think there are product smells. Product smells are what your intuition tells you about new product development and the sense of whether the product will become a Win or Fail.

Microsoft has had its share of developments and early release products with a ‘product smell’.

Let me give you some examples from my personal experience with Microsoft projects which were Fails. With the context established of products which failed, I’ll discuss why I think LightSwitch will be a Win.

Fifteen years ago I worked in a development group responsible for creating server management software. The company sent me to attend a vendor only conference in Redmond where Microsoft showed early bits of “OLE Management Framework”. (Hey, this was a before Microsoft decided to rename Object Linking and Embedding to COM.) That framework never saw the light of day. Parts of it may have morphed to become part of WMI, but it I saw no more of the OLE Management Framework. In my opinion, the market was not ready for that framework. The developer community had not embraced ‘OLE interfaces’ and Windows servers were not widely deployed in the enterprise. Companies had little incentive to develop management applications on top of such of a framework.

I’m sure we can all name some Microsoft projects which “had the smell”: Bob, Clippy, and most recently Microsoft Kin.

Microsoft has had a number of product and framework developments which died a slow death. There are a number of examples of projects which initially appeared to have a bright future, but after months of development, the company stopped work on the project and the bits and IP morphed into other products and product teams.

Some examples which come to mind are WinFS, Oslo and Project Quadrant, and one, which for me, hit close to home– MBF (Microsoft Business Frameworks)

LightSwitch appears different than these Failed projects.  I believe it has the potential to be a wildly successful product. Let me explain more why I believe this.

I use to work on the Microsoft Business Framework team.

In 2001, due to the investments which Microsoft was making at the time in the Business division and the MBF project, MBF appeared to have a great future. Microsoft spent millions of dollars to acquire several companies, Great Plains, Navision, and Solomon, with the intention of consolidating their business applications into one framework and one application.

Let me state my case using some clips from a news article  made in 2002:

“Microsoft is in for the long haul as far as its business applications are concerned with a 10-year development plan and a new Microsoft Business Framework to support the basket of disparate applications offered under the Microsoft Business Solutions banner. ….
The expanding technology stack is part of Microsoft Business Solutions’ goal to provide end-to-end software support for the SME business sector via an integrated application platform, and attempts to address the issue of how the division will manage and integrate its disparate mix of applications which include those from Great Plains and Navision plus its own home-grown offerings. With this proto-framework Microsoft is aiming to change the perception of what constitutes the base for an application platform, said Edwards.

If there were any doubts over how big an effort Microsoft planned to make in the applications mid-market they are rapidly being dispelled. The division has been identified as one of the seven pillars of the wider Microsoft business and while it only produces revenue of $0.5bn at the moment, a paltry sum compared to that of some of Microsoft’s other divisions, the goal is to be generating revenue of $10bn in 10 years time. Edwards says the strategy is a 10-year gamble aimed at getting mid-market companies connected…..”

I remember the mantra $10 billion in 10 years very well. With so much investment made in creating the new division and creating product teams, who was I to argue otherwise in 2002?

A few years later it was a different environment:

From a news article in 2005:

“… Microsoft Business Framework (MBF) is no more.

The new strategy is to make the various technologies that were to comprise MBS available as part of a variety of other currently shipping and soon-to-be-delivered Microsoft products.

On Tuesday, Microsoft announced internally that it had reassigned the couple hundred MBF team members to other product teams, primarily the Visual Studio and Dynamics units, inside the company. Microsoft officials made the company’s decision public on Wednesday.

MBF was to be a set of developer tools and software classes designed to ride atop the Microsoft .Net framework. MBF was developed primarily by Great Plains Software team, which Microsoft acquired in 2001. Microsoft was working to build a number of its products — including the Microsoft Business Portal, the next version of its Visual Studio .Net tool suite and its “Project Green” wave of ERP/CRM products — all on top of the MBF layer.

When Microsoft decided in August, 2004 to remove the Windows File System (WinFS) functionality from Windows Longhorn/Vista and Longhorn Server, MBF was one of the casualties
. At that point, Microsoft refused to pin a delivery-date target on either WinFS or MBF.

As of April this year, however, Microsoft officials revealed that their plan was still to deliver MBF as a standalone set of classes and libraries. Microsoft had delivered one MBF test build to about 40 customers and software developers who were experimenting with the bits. Microsoft’s goal was to deliver the final MBF framework toward the end of 2007, Darren Laybourn, general manager of MBF, told eWEEK.”

Why It’s Different This Time

I don’t think LightSwitch has a future of dimming out like MBF.

Firstly, there’s a market need for a tool like LightSwitch. This market need will drive adoption as more developers and business analysts become aware of how cost effectively they can create business applications.

The business application ecosystem needs a tool which removes the need for non-programmer Business Analysts to construct an application without requiring a deep knowledge about n-tier development, T-SQL commands, and application plumbing construction.

But, that tool needs to provide extensibility points to allow programmers to hook into the tool for custom models and to add out of box functionality. For example, a business application generator needs to allow a programmer hooks to use other .NET frameworks like Work Flow Foundation to add in functionality that’s not in the delivered product.

If Microsoft has learned anything since 2002 about the business application space, it’s that it continues to be a fragmented market and the needs of different businesses make a single solution hard to implement. After a decade, the company still has three business products—Dynamics SL, Dynamics GP, and Axapta. Ease of use coupled with extensibility points is key to the success of a product to build business applications.

Unlike MBF, LightSwitch has a growing and vibrant user community in its Beta 1 release. MBF bits were not released to the developer community, there were no online tutorials and public facing technical evangelists.

LightSwitch is providing many of the concepts which MBF evangelized back in 2002, which is why I think the LightSwitch team “gets it”.

Let me point out a few slides from a PDC 2003 presentation.

Developing Business Applications Using the Microsoft Business Framework Overview DAT340.ppt

clip_image001

clip_image002

clip_image003

clip_image004

clip_image005

Hmm… Data Entities, Entity Validation, Business Logic Abstraction, Persistent Object Data Abstraction (as in data source connections of external databases, Sharepoint, or WCF RIA Services?)

With little editing, these eight year old slides could be used today in a LightSwitch presentation.

The legacy MBF experience sure appears to be reemerging into LightSwitch.

This may well be in part because some prominent members of the LightSwitch team worked on MBF and Dynamics GP.

I mentioned earlier in this posting about the experience of the people behind LightSwitch and why it piqued my interest when I first learned about it.

Steve Anonsen and Dan Seefelt are members of the LightSwitch team. Both were key members of the Dynamics Great Plains product development and later, MBF. It certainly appears they are bringing their decades of experience of what works and what doesn’t work in business application development to LightSwitch.

Steve and Dan are very activity in the LightSwitch forum, quickly answering early adopter’s questions.

In the video Inside LightSwitch, you can watch Steve give an overview of LightSwitch architecture.

Summary

So those are a few of my opinions, with a basis of forming those opinions, of why I believe LightSwitch has the potential to ‘knock it out of the ball park’ for business application product development. This is why I’m investing some of my free time to kick the tires on the early bits and become an early adopter.

I’m curious to hear your comments.

Do you think LightSwitch has the potential to be successful like Visual FoxPro or will early adopters be the last ones out to turn off the lights?

Posted in LightSwitch | 28 Comments