Download Sample
Problem
We often hear about customising business rules and logic. A lot of people have trouble with figuring out how to do this. Often, when software is developed, we rush the software out the door for one customer, but then realise that when we attempt to give the next customer the same software, the logic doesn't quite fit. Perhaps Customer A has a mandatory field while Customer B doesn't always want to fill that value in.
Perhaps your customer wants to see a list of sales on screen that are about $100. This could be done with an SQL query but what about a case where the customer wants to recursively search through a list of sales related to other sales?
These are scenarios that come up time and time again. Logic that might change can't be hard coded.
Solution
Windows Workflow (WF) is a good solution to this problem. What is WF?
Forget all the hype about WF. People talk about using it to map business processes, people use buzz words and so on. Ignore all that rubbish. WF is simply a way of programming without writing code (or at least very little code). Basically you pass arguments in to a WF activity, it does some processing and then spits out the result. Sound familiar? It does and that it is because it is no different to executing normal code.
Except, WF allows you to store logic in a Xaml file rather than a DLL. This means that you don't need to compile the logic and even better Microsoft supplies an editor control to edit the logic. So, you can create hooks in your code when leverage various WF workflows. It's very simple.
Sample App - WorkflowEditor
This is a very simple WPF app. It leverages the WF editing control. It simply allows you to open a WF Xaml file, edit it and then save it. To see how this works, simply run the app and open the file Add.xaml in the bin\debug folder.
The Add.xaml workflow simply assigns the output variable by adding the two input variables together. Trying adding some if statements and so on.
The toolbox you get in this editor is very simple. You can add all kinds of Workflow Objects (google this stuff). The toolboox editor is editable after app compilation so if you're onsite you can even customise your own toolkit.
Sample App - ExecuteWorkflow
This app simply passes the input argumets on screen, passes them in to a workflow and then displays the result on screen. Try running the Add.xaml workflow which is in the WorkflowEditor project. Try editing it using the Workflow editor, and then re-running this sample.
Conclusion & Thoughts
WF is still not the answer to all kinds of logic customisation. It's still slower than code. Also, it's much more awkward coding with diagrams instead of code. However, it does open up opportunities. In some cases, you might be able to confirm logic with customers, hire configuration people to set up your instances, perhaps even write the logic in to the contract. Of course you could just compile the logic in to a DLL and maintain it, but this has always been a headache in the past and if you want to pursue this path, you're going to need to create a code editor and leverage a compile inside your app with takes time. WF is a good answer in a lot of situations.
Download Sample
Christian Findlay's Development Blog
This blog is dedicated to quality programming techniques, code samples and general programming advice. This blog is geared toward the .Net, Silverlight, WCF, Windows Workflow and related Microsoft technologies.
Tuesday, February 22, 2011
Soft Coding Logic with WF
Labels:
c#,
dynamic,
dynamic logic,
logic,
softcoding,
vb,
wf,
windows workflow,
workflow editor
Monday, February 7, 2011
Shopping Cart in MVC2
Download Source
Problem
Classic ASP.Net has a convoluted programming model.
Solution
MVC2 is a better programming model for a shopping cart app. This project is a complete Shopping Cart. I evaluated how much work it was going to be to write the app in ASP (even though I worked with ASP for a long time) and I realised that writing it in MVC2 would be easier.
I'm not going to go in to technique too much here. The code here speaks for itself so please download the source code. However, I will give some info on the different technology this website uses.
By the way, if you need to create an MVC2 Shopping Cart, I strongly recommend having a look at this code because you will have most of the fundamental functioanlity here. The functionality allows for user administration and editing products.
MVC2
MVC2 Divides models (classes that house data), views (ASCX pages) and controllers. Controllers are code files that control the way the view works. This division makes coding in ASP a lot cleaner. There are also some other advantages. It also makes dynamic page updates a lot cleaner. I was never a fan of the UpdatePanel in ASP. While in MVC2, you can do a partial page update on an ASCX withou needing anything like an UpdatePanel.
Silverlight & RIA
The sample app has some Silverlight Charts using RIA Services. This is a good example of how Silverlight can be added in to an MVC2 app in order to provide a nicer UI.
Entity Framework
The backend uses EF to persist data. I found this data layer a bit clunky but I like the way you can do very sophisticated LINQ queries on the data and the data layer remains database independent.
LINQ & Lambda
I used loads of LINQ and lambda to show of how well EF works with these technologies.
Sitemap
This sitemap library is a 3rd party tool.
Partial Page Rendering without JavaScript
ASP MVC2 makes partial page rendering very simple. It has a clean model for partial updates without having to write the actual JavaScript in many cases.
Data Paging (Partial Rendering)
The data paging library is a 3rd party tool.
ASP Membership Provider
This app uses the ASP membership database and is separated from the app database. There is a script provided to create both databases from scratch. The application pays attention to roles and gives the "Admin" user differernt privildeges.
SQL Server
That's obvious.
WCF
There is a dummy payment service to mock up a credit card payment system.
Get It Running
Download Source
Problem
Classic ASP.Net has a convoluted programming model.
Solution
MVC2 is a better programming model for a shopping cart app. This project is a complete Shopping Cart. I evaluated how much work it was going to be to write the app in ASP (even though I worked with ASP for a long time) and I realised that writing it in MVC2 would be easier.
I'm not going to go in to technique too much here. The code here speaks for itself so please download the source code. However, I will give some info on the different technology this website uses.
By the way, if you need to create an MVC2 Shopping Cart, I strongly recommend having a look at this code because you will have most of the fundamental functioanlity here. The functionality allows for user administration and editing products.
MVC2
MVC2 Divides models (classes that house data), views (ASCX pages) and controllers. Controllers are code files that control the way the view works. This division makes coding in ASP a lot cleaner. There are also some other advantages. It also makes dynamic page updates a lot cleaner. I was never a fan of the UpdatePanel in ASP. While in MVC2, you can do a partial page update on an ASCX withou needing anything like an UpdatePanel.
Silverlight & RIA
The sample app has some Silverlight Charts using RIA Services. This is a good example of how Silverlight can be added in to an MVC2 app in order to provide a nicer UI.
Entity Framework
The backend uses EF to persist data. I found this data layer a bit clunky but I like the way you can do very sophisticated LINQ queries on the data and the data layer remains database independent.
LINQ & Lambda
I used loads of LINQ and lambda to show of how well EF works with these technologies.
Sitemap
This sitemap library is a 3rd party tool.
Partial Page Rendering without JavaScript
ASP MVC2 makes partial page rendering very simple. It has a clean model for partial updates without having to write the actual JavaScript in many cases.
Data Paging (Partial Rendering)
The data paging library is a 3rd party tool.
ASP Membership Provider
This app uses the ASP membership database and is separated from the app database. There is a script provided to create both databases from scratch. The application pays attention to roles and gives the "Admin" user differernt privildeges.
SQL Server
That's obvious.
WCF
There is a dummy payment service to mock up a credit card payment system.
Get It Running
- Run the script shopping_cart.sql in SQL Server. I used SQL Server 2008 but I think it will work in 2005 as well. (Check that the path for the files exist - 'c:\Databases' )
- Open the solution.
- Point the web.config at the databases on your local machine
- Run
- Log in as "Admin/admin", or "Andreat/aaaaaa", or create a new profile. Note: the different options as an admin user
Download Source
Labels:
asp,
mvc2,
partial page rendering,
RIA,
silverlight,
wcf
Friday, February 4, 2011
Dynamic WCF Services & Silverlight
Sample: Get Sample
Problem
Everybody knows that you need to some kind of communication layer to access your database these days. In the past you would use Web Services, and now WCF services are popular. The problem for a lot of teams is that out of the box these services remain static while a customer's database is constantly changing.
There are basically two kinds of apps. Apps where the database structure will be determined before the application is written and will not change in future. These apps have the same structure no matter which customer they go out to. Generally these apps are not enterprise level apps and they generally do a simple task in a well defined way which is not customisable.
However, in modern enterprise architecture apps, it's a given that the database will change from customer to customer. This is not really a problem for WCF or Silverlight. However, if you follow the out of the box Microsoft solution, it seems very difficult. Generally, people tend to use SlSvcUtil, or Visual Studio's build Service Reference tools to achieve the client side of the equation. These tools may sound like a good solution but they cut you off at the knees in a very subtle way which I will explain in the solution.
Before I go any further, you could pursue Microsoft RIA Services. These services are definitely along the lines of what I am suggesting. RIA Services . Although I personally find them a bit clunky and intrusive upon my programming style. I'm not sure but they may actually solve the problem that I am talking about here.
Solution
We must take control of the service side, model objects (Person, Car, whatever houses the data), and the client side. The model objects will share code across the service side (.Net) and the client side (Silverlight). The model objects will be based on the tables in the database. The end goal is that the only assembly that will need to be redeployed is the model assemblies on the client and server side. This is a necessity because the models must match the database.
There is an assumption though. This solution will assume that you have some kind of generic data layer. If a table is added to the client's system, the data layer should not have ot be rebuilt in order to deal with the situation. But, if your data layer is not this flexible, it's OK. You may have to redeploy the data layer as well.
The service itself should have the standard CRUD operations (Create, Read, Update, Delete). But I like to cut the CRUD thing down to Get, Save and Delete. You could create an operation for each database table in the customer's system, however, this defeats the purpose of this exercise. You could make a service that looks like this:
This service will allow you to create, read, update or delete records in any database table in the system as long as a the corresponding model class exists.
Service Contract
This must use a method (I have used GetKnownServiceTypes) to determine which models can be passed across the wire. This is crucial and must exist on both the client and server side. This is the reason that SlSvcUtil does not provide an adequate solution. When you pump out a client proxy using SlSvcUtil it hard codes the list of classes that are allowed to be passed across WCF in to the CS file. That means that if you wanted to add a class to the list, you would have to re-run SlSvcUtil, recompile and redeploy our reference dll. This is not good for maintaining your software.
Client Side Service Contract
The client side service contract must match the server side one. However, we can't just use the existing one because Silverlight requires us to use async methods. Keep an eye out for the async framework though because with any luck, we might be able to just leverage the interface from the actual service itself (we can do that in .Net but not Silverlight).
Client Side Proxy
The proxy I have created is very similar to the one generated by SlSvcUtil. I wish SlSvcUtil did what we needed it to do here (allow for a dynamic method for the KnownTypes) but it doesn't. Meantime, please use my snippet to create the bits and pieces you need for the client. Just clicks Tools->Code Snippet Manager in VS to import the snippet. Put it in the My Code Snippets section.
Model Library
This should be separate from the rest of your app. This is theoretically, the only thing in your app that should change and it should change in concert with changes to your database. Bare in mind that you need a smart data layer to use the model to figure out how to persist data to the database.
Data Access Layer
I'm deliberately leaving this open. You might be able to use something like Entity Framework. Or, you can create your own. The main thing is that you will need to separate it from your model objects but the DAL itself should load and save data based on the structure of the model objects. It should not explicitly need a function like GetPerson. Instead it should have something like GetEntity. I might talk about this in another post.
Running the Sample
I recommend deploying the WCF service to IIS and ensuring that there is a valid clientaccesspolicy.xml setup (please google this). Then you can run the Silverlight app from VS and point the servicereferences.clientconfig at your deployed WCF app. I have never been successful in getting a Silverlight app to talk to a WCF service running inside WcfSvcHost (VS's native WCF host).
Conclusion
Anyway, some example source is provided. It should give you some ideas about how to achieve what I have talked about. This is quite simple but as I mentioned, most people get lead astray by using the standard toolset. But, I think in future Microsoft will be improving the SlSvcUtil tool so that it creates better proxies. If you are really smart, you could investigate hooking in to SlSvcUtil to change the code that is outputted. I have done small things with this but it is possible to write an app which catches events that SlSvcUtil goes through and then change the output of the code but this is beyond the scope of this post.
Notes
Thanks to To Html.com for the syntax highlighting.
Sample: Get Sample
Create Proxy Code Snippet: Get Snippet
Problem
Everybody knows that you need to some kind of communication layer to access your database these days. In the past you would use Web Services, and now WCF services are popular. The problem for a lot of teams is that out of the box these services remain static while a customer's database is constantly changing.
There are basically two kinds of apps. Apps where the database structure will be determined before the application is written and will not change in future. These apps have the same structure no matter which customer they go out to. Generally these apps are not enterprise level apps and they generally do a simple task in a well defined way which is not customisable.
However, in modern enterprise architecture apps, it's a given that the database will change from customer to customer. This is not really a problem for WCF or Silverlight. However, if you follow the out of the box Microsoft solution, it seems very difficult. Generally, people tend to use SlSvcUtil, or Visual Studio's build Service Reference tools to achieve the client side of the equation. These tools may sound like a good solution but they cut you off at the knees in a very subtle way which I will explain in the solution.
Before I go any further, you could pursue Microsoft RIA Services. These services are definitely along the lines of what I am suggesting. RIA Services . Although I personally find them a bit clunky and intrusive upon my programming style. I'm not sure but they may actually solve the problem that I am talking about here.
Solution
We must take control of the service side, model objects (Person, Car, whatever houses the data), and the client side. The model objects will share code across the service side (.Net) and the client side (Silverlight). The model objects will be based on the tables in the database. The end goal is that the only assembly that will need to be redeployed is the model assemblies on the client and server side. This is a necessity because the models must match the database.
There is an assumption though. This solution will assume that you have some kind of generic data layer. If a table is added to the client's system, the data layer should not have ot be rebuilt in order to deal with the situation. But, if your data layer is not this flexible, it's OK. You may have to redeploy the data layer as well.
The service itself should have the standard CRUD operations (Create, Read, Update, Delete). But I like to cut the CRUD thing down to Get, Save and Delete. You could create an operation for each database table in the customer's system, however, this defeats the purpose of this exercise. You could make a service that looks like this:
using System;
using System.ServiceModel;
namespace DynamicWCFService
{
public interface IService
{
[OperationContract(AsyncPattern = true)]
[ServiceKnownType("GetKnownServiceTypes", typeof(ServiceKnownTypeGetter))]
IAsyncResult BeginGetEntity(string entityTypeName, object entityKey, AsyncCallback callback, object state);
IEntity EndGetEntity(IAsyncResult result);
[OperationContract(AsyncPattern = true)]
[ServiceKnownType("GetKnownServiceTypes", typeof(ServiceKnownTypeGetter))]
IAsyncResult BeginSaveEntity(IEntity entity, AsyncCallback callback, object state);
IEntity EndSaveEntity(IAsyncResult result);
[OperationContract(AsyncPattern = true)]
[ServiceKnownType("GetKnownServiceTypes", typeof(ServiceKnownTypeGetter))]
IAsyncResult BeginDeleteEntity(IEntity entity, AsyncCallback callback, object state);
bool EndDeleteEntity(IAsyncResult result);
}
}
This service will allow you to create, read, update or delete records in any database table in the system as long as a the corresponding model class exists.
Service Contract
This must use a method (I have used GetKnownServiceTypes) to determine which models can be passed across the wire. This is crucial and must exist on both the client and server side. This is the reason that SlSvcUtil does not provide an adequate solution. When you pump out a client proxy using SlSvcUtil it hard codes the list of classes that are allowed to be passed across WCF in to the CS file. That means that if you wanted to add a class to the list, you would have to re-run SlSvcUtil, recompile and redeploy our reference dll. This is not good for maintaining your software.
Client Side Service Contract
The client side service contract must match the server side one. However, we can't just use the existing one because Silverlight requires us to use async methods. Keep an eye out for the async framework though because with any luck, we might be able to just leverage the interface from the actual service itself (we can do that in .Net but not Silverlight).
Client Side Proxy
The proxy I have created is very similar to the one generated by SlSvcUtil. I wish SlSvcUtil did what we needed it to do here (allow for a dynamic method for the KnownTypes) but it doesn't. Meantime, please use my snippet to create the bits and pieces you need for the client. Just clicks Tools->Code Snippet Manager in VS to import the snippet. Put it in the My Code Snippets section.
Model Library
This should be separate from the rest of your app. This is theoretically, the only thing in your app that should change and it should change in concert with changes to your database. Bare in mind that you need a smart data layer to use the model to figure out how to persist data to the database.
Data Access Layer
I'm deliberately leaving this open. You might be able to use something like Entity Framework. Or, you can create your own. The main thing is that you will need to separate it from your model objects but the DAL itself should load and save data based on the structure of the model objects. It should not explicitly need a function like GetPerson. Instead it should have something like GetEntity
Running the Sample
I recommend deploying the WCF service to IIS and ensuring that there is a valid clientaccesspolicy.xml setup (please google this). Then you can run the Silverlight app from VS and point the servicereferences.clientconfig at your deployed WCF app. I have never been successful in getting a Silverlight app to talk to a WCF service running inside WcfSvcHost (VS's native WCF host).
Conclusion
Anyway, some example source is provided. It should give you some ideas about how to achieve what I have talked about. This is quite simple but as I mentioned, most people get lead astray by using the standard toolset. But, I think in future Microsoft will be improving the SlSvcUtil tool so that it creates better proxies. If you are really smart, you could investigate hooking in to SlSvcUtil to change the code that is outputted. I have done small things with this but it is possible to write an app which catches events that SlSvcUtil goes through and then change the output of the code but this is beyond the scope of this post.
Notes
Thanks to To Html.com for the syntax highlighting.
Sample: Get Sample
Create Proxy Code Snippet: Get Snippet
Labels:
data layer,
database changes,
dynamic,
ria services,
service,
ServiceKnownType,
silverlight,
wcf
Subscribe to:
Posts (Atom)