Welcome

You have reached the blog of Keith Elder. Thank you for visiting! Feel free to click the twitter icon to the right and follow me on twitter.

Life With Visual Studio 2008

Posted by Keith Elder | Posted in .Net, Asp.Net | Posted on 01-08-2007

0

Visual Studio 2008 Beta 2 was recently released and it is now to the point where one could use it on a daily basis.  For me, there are a few things that are stopping me from jumping ship from VS2005 straight to VS2008 Beta 2.  A few of those revolve around the ability to install guidance packages such as the Web Service Software Factory for WCF and a few others.  

The good news is More Wally has already taken the plunge for those of us that are procrastinating and is reporting his ups and down with VS2008 in a series called Life With Visual Studio.  Keep that on the radar as he works through converting projects, etc. 

Resharper Breaks Intellisense After Uninstall

Posted by Keith Elder | Posted in .Net | Posted on 09-06-2007

29

A few weeks ago I installed Resharper trial to give it a try.   During this time I was doing some development on a brand new project so I figured it would be a good test to see how it works  / performs.   It wasn’t long until I noticed some serious performance drops in Visual Studio so I turned on the Resharper feature which keeps tabs on the memory it is using in the status bar.  My small solution with a few projects was eating up about 120MB! 

This week at TechEd I won a copy of CodeRush and Refactor! from http://www.devexpress.com.  I know Dustin Campbell and Mark Miller who both work at developer express and I’ve seen them both do several demos on their product.  I was a fan but knowing they sponsor a lot of CodeCamps and other events like TechEd I knew I would eventually run into a copy.   Once I got the license I uninstalled Resharper and then installed CodeRush.  Played with it some and immediately noticed that intellisense wasn’t working anymore.  Of course I blamed CodeRush and went to their support site only to find a link to the Resharper site.   Apparently when uninstalling Resharper it disables intellisense so you have to re-enable it.  To do this open up the tools menu then Text Editor and then C#.  Under there you will need to recheck “Auto list members” and “Parameter information” to get intellisense enabled as shown below. 

image

Hopefully this will help others that run into the same problem.  So far I’ve only coded a little in VS2005 with CodeRush and Refactor! installed but so far it works as described.

What Acropolis Is and Isn’t

Posted by Keith Elder | Posted in .Net, Programming, Smart Clients | Posted on 08-06-2007

0

Ayende wrote a post about Acropolis as another executable XML language.  Then a few other people chimed in on comments about Acropolis being another example of Microsoft providing tools to turn bad developers into mediocre developers.  I think the point of Acropolis has been totally lost in this conversation so please allow me to weigh in.

To start with WPF is already expressed in XML.  This has been known for awhile and we’ve all seen amazing results of expressing the UI declaratively.  Look at all the eye candy WPF and Silverlight has dazzled us with over the past several months as an example.  Acropolis is simply leveraging the new WPF stack so to call it an executable XML language is a little far fetched.  Of course it is true that XAML generated to display WPF applications is in XML format but it isn’t a language it is merely parsed.  Calling Acropolis an executable XML language is like calling a component or control that ships out the box with the framework a language because that is what Acropolis is, additional controls that are going to be shipping to enhance WPF which in return will help us composite our client applications better.  

Acropolis isn’t a language but merely an extension of controls and patterns to WPF similar to the Smart Client Software Factory and CAB built leveraging the richness of Windows Presentation Foundation.   That is the Forrest Gump definition of how I would explain it.

We’ve already seen and tried to solve a lot of the problems developers face in building rich client applications with SCSF and CAB.  Acropolis is no different in what it is trying to solve just in how it is put together.  Meaning Acropolis is built on the WPF stack rather than built on object oriented design patterns.  Under the hood there are design patterns going on I am sure but they are abstracted to controls. 

To give you an analogy here is how I would think about it.  To me it is no different than Asp.Net 2.0 shipping the Login controls.  This is an example of a common problem web developers face and an abstract way of dealing with that problem.  Acropolis to me is no different in the fact that there are inherent things as client developers we have to do each and every time we start a client application.  Acropolis will hopefully help us solve these problems, but it isn’t a new XML language.  It also has nothing to do making bad developers mediocre developers as one commenter pointed out.  Just as the login control bundled with Asp.Net 2.0 didn’t make bad developers mediocre developers.

The point of Acropolis is to take things that are “common” that client developers have to do and abstract the repetitiveness of building composite applications into something that can be reused in the framework.   As Brad Abrams pointed out in his comment there is still separation of code and business logic. 

I saw at lengthy talk on Acropolis at TechEd done by Kathy Kam and mostly what I saw was a set of new controls that will assist client developers in building out the plumbing of smart client applications faster.  It is still new but the direction it is going will in my opinion solve what it is trying to solve if done correctly. 

Technorati tags: , , , ,

TechEd Day 2

Posted by Keith Elder | Posted in .Net, Asp.Net, Smart Clients, Web Services | Posted on 07-06-2007

0

It is day two of TechEd and my feet and legs are killing me.  My feet didn’t get a chance to rest after the four day whirlwind tour of Disney World.  I told my wife that I was going to have to go to TechEd just so I could rest 🙂  Here is day two’s activities.

Biztalk WCF Adapter

The first session I attended this morning was an overview of the WCF Adapter for Biztalk which is in the R2 release.  Don’t get your hopes up just yet because it isn’t available.  I was told it  wouldn’t be out until 3rd quarter.  The good thing is the WCF adapters bring a lot of cool things to the table.  I can’t remember all the reasons they gave but the one that a lot of people will use is the ability to do TCP binary messages to Biztalk I am sure.  Actually there are seven WCF adapters, one for each binding type.  The demo they showed was a message from a smart client being sent to Biztalk, and then Biztalk hitting SQL Server and then another service.  The orchestration had to route the message and handle the transaction so if the write to SQL Server failed or the the other service failed then it rolled back the data in SQL Server.  Definitely a real world example and it shows the ability of WCF to handle transactions.   

Wondering Around the Expo

After the Biztalk session I was walking from the north building back to the south building and ran into Bruce Thomas at the MVP booth.  I also saw Joe Healy, Jeff Palermo, DonXML, Miguel Castro, and Joe Fuentes.  I then walked down and caught some of the “Speaker Idol” that Carl Franklin and Richard Campbell were hosting.  This was pretty cool and I wish I had heard about it sooner so I could have entered.  The way it works is a speaker gets up on stage and does a 5 minute presentation.  Then they get judged by a bunch of Regional Directors.  It is a really great way to get feedback about your presentation skills no doubt.  The big challenge is doing just a 5 minute talk!

Smart Client Applications in Visual Studio 2008

After lunch I went to a presentation on the new smart client features in Visual Studio.  Some of these are nothing new in terms of new information (linq and wpf) but they are technically “new” in 2008 and some are new exciting features.

Working With Data

LINQ is of course the new way to work with data in VS2008.  The demos they showed were just connecting to a database locally which isn’t a true Smart Client architecture in my opinion since it isn’t services based.  Nevertheless, LINQ is new in VS2008 and we’ll all love him, hug him and call him George.

Taking Data Offline

This is something that I hadn’t seen yet and it really peaked my interest since we have a lot of uses for it.  SQL Server Compact Edition 3.5 which is in beta right now will be available to us.  You can read about the new features here.  The nice thing about 3.5 is it can be deployed with your application through ClickOnce and it doesn’t run as a service.  It also supports about 2-4 GBs of data which should be PLENTY for any application that needs to run offline.  The other piece is the Sync Agent which is tasked with the joy of keeping data in sync.  As soon as they said this I immediately thought “Smart Clients shouldn’t connect to the database directly” and as soon as I thought that the presenter said it supports sync via services.  Hotness! 

User Profiles

Something else that is new is Client Application Services.   Today web applications can store user profile information which is used for themes, preferences and so on but it is tough for Smart Clients that are service enabled.  Client Application Services allows us to reuse the existing profile and role based mechanisms Asp.Net offers today to allow us to centrally store profile information.  This may not sound like a big deal but today we have to create a lot of plumbing in Smart Clients to store application preferences and profile information away from the client’s desktop machine.  Storing preferences on the desktop machine doesn’t allow users to move from machine to machine and have the application setup the same way. Client Application Services fixes this by leveraging existing functionality so this will be good.  There will be a new services tab when you right click on properties on your project.  In the services tab you point to a web server which will hold the profile settings and any settings you create in your app are stored and retrieved from there. 

User Experience

Another new feature in VS2008 is going to be WPF.  They call this the “user experience” but a lot of us already know about WPF.  This will change how we build Smart Clients no doubt but we’ve been hearing about WPF since 2005 so nothing to see here.  Moving on.

Deployment

In VS2005 we got a new deployment technology called ClickOnce.  In VS2008 ClickOnce doesn’t go away, it just gets enhanced.  There are six new enhancements to it but the one I like the best is the ability to change the deployment URL and not have to rebuild the entire manifests.  I didn’t write them all down but there was something mentioned about ISV branding in ClickOnce in VS2008. 

Reusability – Acropolis

This was the new bomb shell that was dropped called “Acropolis”.  Acropolis is a framework that simplifies building composite clients and will replace the Smart Client Software Factory moving forward.  Bryan Adams just blogged about this on June 4th so read his initial post if this is your first time to hear about it (just remember you heard it hear first 🙂 ).  After you read that, read this one with more questions and this one with additional information including video and live docs.

Certification Study Hall

After the what’s new in Visual Studio 2008 I went to the certification center where I started practicing some certification exams.  At TechEd you can take certification exams for $50 here onsite as well as go through tons of test questions.   I studied until I just about fell asleep and then rolled to the hotel.  Day two is now in the books.

Part 2: Leveraging Workflow Foundation – Invest in Your Workflow Infrastructure

Posted by Keith Elder | Posted in .Net, Web Services, Workflow Foundation | Posted on 28-05-2007

13

In Part 1 of Leveraging Workflow Foundation we discussed how Workflow Foundation is just an API.  Since APIs don’t provide business value out of the box, it is important engineers exploring Workflow Foundation for the first time approach it in the same manner they would any API: write once, run everywhere.  In other words, instead of building out the workflow components for one application, look at it from the 10,000 feet view.  This is of course going to take more time than one might originally think so be sure to allow for this in development time.  We’ll look at the basics engineers starting with Workflow Foundation will need to think about to invest in their workflow infrastructure.  Who knows, we may even find some rusty washers and shinny pennies along the way.

Think about workflow from a central service for your business not just within one application.  Think about workflow outside of the box.  Think about reusability.  Think about a central rules engine.

While this will not be a comprehensive guide on how to build out one’s infrastructure with Workflow Foundation, I do want to point out several entry points everyone should consider.  The idea is to invest time in Workflow Foundation just as one might in invest other areas of .Net like Asp.Net for example.  I use Asp.Net as an example because most engineers that build Asp.Net web sites have some type of reusable framework they can apply to other web sites they build.  If the same principal is applied to Workflow Foundation and done correctly, it could pay off huge dividends for a business.

The Big Picture From a 10,000 Feet View

We understand we need to invest in our workflow infrastructure.  What are the things we need to spend our time on to make Workflow Foundation more reusable across our teams?  Let’s first look at our goal.  Our goal is to build out a core workflow infrastructure that can be reused among various projects, teams, and applications.  

Now that our goal is set, here are the things we need to focus on to make this a reality:

  1. Provide a central location where workflows can be stored.
  2. Provide a central location where rules can be stored.
  3. Provide a central service where workflows can be invoked.
  4. Provide a central service and API where rulesets can be manipulated and invoked against workflows or instances of any object.
  5. Provide a custom user interface to easily create, modify, update, track and manage existing workflows and rules.  Also this should have the ability to deploy workflows and rules to different environments (test, beta, prod).

As we see there is A LOT that needs to be done to build out a reusable infrastructure.  Let’s start with the first two items above since these are relatively easy to accomplish.   The reason I used the words “easy to accomplish” is because workflows and rules associated with workflows can be expressed in XML.  Once we persist our workflow to XML, which is called XOML, it becomes trivial to store the XOML in a database.  Rules associated with workflows are already created in XML and this makes it easy to store these.  The harder one to deal with is the workflow though.  More on that later. 

When we create our database structures to store workflows and rules XML it is important we do not build our tables in a way where rules are always tied to a workflow.  In other words don’t build a single table.  Workflows and rules should be stored separately and by doing so gives us some nice reusability with the rules engine as we’ll see later on.  Remember we are trying to create not only a reusable workflow infrastructure but a reusable rules engine as well.  Now that we understand workflows and rules can be stored in a database let’s look at how this will be accomplished.

Storing XOML Workflows in the Database

As mentioned earlier we can express our workflows in XML.  At the time of this writing Visual Studio supports two types of workflows.  A code behind workflow and a XOML workflow.  It is the XOML workflow type that we are interested in.  Since the XOML workflow is essentially XML, we can easily store it into a database. 

To persist workflows we need to first create our workflows as XOML based workflows.  With a little bit of code we could persist the XOML into a database.  The next question is how do we instantiate workflows from XOML.   The answer is easy but it is a matter of knowing where to look.  To create an instance of a XOML workflow we have to dig a little deeper into the APIs but not too far.  The method we are going to look at is CreateWorkflow().  CreateWorkflow() has six overrides and it is the sixth override that provides us the entry point we need not only for workflows but also to pass in rules our workflow would use.  Here is the syntax of it:

public WorkflowInstance CreateWorkflow (

                XmlReader workflowDefinitionReader,

                XmlReader rulesReader,

                Dictionary<string,Object> namedArgumentValues

            )

 

The reason this override method in particular is interesting is it allows us to pass in all the arguments we need to kickoff our workflow including our XOML, our rules and any parameters the workflow needs. 

When you first add a workflow object to your solution, but sure to select the one that is XOML based, here is a screen shot from Visual Studio.

Assuming an interface is built to manipulate workflows outside of Visual Studio, using the XOML based workflow will allow us to adjust the workflows in real time without having to recompile assemblies and redeploy them (assuming the code behind doesn’t need modified).  Be sure to download the workflow samples available as it contains examples of how to rune workflows with XOML.   The main thing missing from Visual Studio though are tools to assist in running and deploying XOML based workflow definitions so plan on devoting a lot of time to this area as the documentation and tools available are slim.  Keep your eye on the prize though! 

Just for the record, here is a sample hello world XOML workflow to give you an idea what the XOML looks like:

<SequentialWorkflowActivity x:Class=WorkflowLibrary1.Workflow2 x:Name=Workflow2 xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml xmlns=http://schemas.microsoft.com/winfx/2006/xaml/workflow>

    <CodeActivity x:Name=codeActivity1 ExecuteCode=codeActivity1_ExecuteCode />

    <CodeActivity x:Name=codeActivity2 ExecuteCode=codeActivity2_ExecuteCode />

</SequentialWorkflowActivity>

 

The first code activity prints “Hello” and the second prints “World”.  Since we’ve expressed this in XML we could easily manipulate the workflow to print “World” then “Hello” simply by moving the codeActivity2 above codeActivity1.  We could do this without needing to redeploy any code.

The hard part of this is tying the ability to persist XOML workflows with the big picture item number five.  Storing our XOML in a database doesn’t necessarily make us agile from a business standpoint, it is the interface the end users (business analyst or other engineers) interact with and the central workflow services we expose that is going to make us more agile.  This is where the majority of your time is going to be spent.  There is good news in that there are numerous samples floating around on the Internet to give you a better idea.  Be sure to checkout the samples here.  You are also going to have to devote a fair amount of time to the ComponentModel to create the desired UI experience to load a workflow from XOML, alter it, and then persist it back. 

As we discussed in part 1 there are rusty washers and this is one of them.  While we can off load workflows to the database we will find there aren’t many tools to assist us in doing so and the art of doing this will seem kludgy and an after thought at best.  I personally spent several hours trying to get workflows to reliably load from the file system and couldn’t.   I’m sure it was something simple I wasn’t doing but the whole process was very inelegant.  Hopefully the Workflow Team will beef up their tool offerings in the next version of Visual Studio to make this more trivial.  Because of the lack of time to devote to this our team decided we would revisit it at a later date when we had more time.

 

Storing Workflow Rules in the Database

We’ve looked at storing workflows so let’s move onto storing rules in the database.  The rules engine aspect of Workflow Foundation turned out to be a shiny penny and one that isn’t talked about much.  #2 and #4 of our big picture items is off loading rules to the database and then creating a central service where rules can be invoked. 

When we add a “policy” activity to a workflow we can associate one or more rules to it.  Once a rule is defined we can also re-use it within the workflow.  That’s great, but what if we want to reuse the same rules again in a different workflow?  This is one reason why we want to off load these rules into a separate location.  When rules are created within Visual Studio by default they are stored in a hidden file called .rules.   The nice thing about the rules is they are already written in XML. Here is a screen shot so you can see how this appears from Visual Studio.

 

This is also where the second parameter of CreateWorkflow() override number six comes into play.  We can easily offload the rules we’ve created into another database table or set of tables and then pass those into the workflow at runtime.  Not only can we leverage the built in rule APIs within Workflow Foundation for workflows we can also utilize this for validating instances of objects that could then be used across multiple applications.   During my exploration, once this light bulb went on I realized that I could really save my team a lot of time.  I started down the path of building out a tool that could not only serve the purpose of storing rules for workflows but also a tool that could be called via a service from any application.  I call the tool “Orbb”.

Orbb – Object Rules Business Builder

According to our goals as outlined above, we knew we wanted to store rules in a database and then expose functionality via a service.  To make ourselves more agile we need an interface to manipulate these rules.  During my exploration of the rules engine that ships with Workflow Foundation it became apparent that rules can be run against ANY INSTANCE OF ANY OBJECT.  This is powerful because it means we aren’t tied to XML like Biztalk for example.  For example we could have a Winform instance that needs to have rules performed against it, or maybe an Asp.Net web page, or may a simple business entity like a purchase order.  As long as it is an “instance” we can leverage the rules engine that ships with Workflow Foundation.

Once this light bulb went off, a few hours later I had a database, WCF service and a user interface to build, manage and centrally store rules for a variety of applications.  Orbb was then born.  Today Orbb is just a proof of concept but the value it could provide is unquestionable.   It is in a very infant stage right now and may never see the light of day but it is far enough along I can share a screen shot with you here.  Here is a screen shot:

The idea is fairly simple.  An application is created within Orbb and then permissions are setup (who can edit / change rules for each application) along with the various environments you need to test your rules (test, beta, prod).  Those that are granted access can then use Orbb to manage not just one application but multiple applications.  Imagine one central service where rules could be stored, validated and retrieved. 

For example, imagine you have a smart client where users can create a new helpdesk ticket.  The business informs you that users aren’t entering enough information in the “what is wrong” textbox and they want you to force them to enter at least 150 characters.  Instead of having to add this rule to your code by hand and re-push it, you could simply launch Orbb, select the form and add the new rule to the form.  Then copy the new ruleset to your test, beta and prod environments without having to redeploy your application. 

This type of flexibility could also be applied to workflows whereby rules change.  Being able to adjust your workflow rules without having to redeploy is definitely worth an investment.   One of the things that came out of Orbb as I worked through it was a generic class that takes any Object and retrieves the rules from a database and then validates the object using the rules.  You could utilize this in a service, Winforms, Asp.Net pages, business objects and more.  I have provided a copy of this below in the “Validating Any Object with Workflow Rules Engine” section.

Conclusion

As you can see there is quite a bit of work that can be done to leverage Workflow Foundation and your mileage will vary in regards to your time / benefit ratio.  In the end it will pay in huge dividends if an investment is done up front, not as an after thought.  In part 3 of Leveraging Workflow Foundation we’ll look at hosting the workflow runtime.  Will we find any rusty washers?  Stay tuned!

Validating Any Object With Workflow Rules Engine

using System;

using System.Collections.Generic;

using System.Text;

using Microsoft.Practices.EnterpriseLibrary.Data;

using System.Data.Common;

using System.IO;

using System.Xml;

using System.Workflow.Activities.Rules;

using System.Workflow.ComponentModel.Serialization;

using System.Workflow.ComponentModel.Compiler;

 

namespace Orbb.BusinesLayer

{

    /// <summary>

    /// This is a generic class that will take any object and process rules

    /// against that object that are defined in a database.

    /// </summary>

    public class ObjectValidation

    {

        private object entity;

 

        /// <summary>

        /// The object that needs to be validated.

        /// </summary>

        public object Entity

        {

            get { return entity; }

            set { entity = value; }

        }

 

        private string ruleSetName;

 

        /// <summary>

        /// Name of the RuleSet that is in the database we need

        /// to use.

        /// </summary>

        public string RuleSetName

        {

            get { return ruleSetName; }

            set { ruleSetName = value; }

        }

 

        private System.Workflow.Activities.Rules.RuleSet ruleSet;

 

        /// <summary>

        /// Deserialized RuleSet object which contains all the rules.

        /// </summary>

        public System.Workflow.Activities.Rules.RuleSet RuleSet

        {

            get { return ruleSet; }

            set { ruleSet = value; }

        }

 

        private RuleValidation ruleValidation;

 

        public RuleValidation RuleValidation

        {

            get { return ruleValidation; }

            set { ruleValidation = value; }

        }

 

 

        private WorkflowMarkupSerializer serializer = new WorkflowMarkupSerializer();

        /// <summary>

        /// Provides the extensible Application Markup Language (XAML) serialization services

        /// to workflow at design time.

        /// </summary>

        public WorkflowMarkupSerializer Serializer

        {

            get { return serializer; }

            set { serializer = value; }

        }

 

        private System.Workflow.Activities.Rules.RuleExecution ruleExecution;

        /// <summary>

        /// Stores state information while executing RuleCondition or RuleAction classes.

        /// </summary>

        public System.Workflow.Activities.Rules.RuleExecution RuleExecution

        {

            get { return ruleExecution; }

            set { ruleExecution = value; }

        }

 

        public ObjectValidation(Object entity, string ruleSetName)

        {

            this.Entity = entity;

            this.RuleSetName = ruleSetName;

 

            // Get the rule from the database

            this.GetRuleFromDatabase();

        }

 

        /// <summary>

        /// Gets the rule from the database as specified.

        /// </summary>

        private void GetRuleFromDatabase()

        {

            Database db = DatabaseFactory.CreateDatabase(“OrbbConnectionString”);

            using (DbCommand cmd = db.GetSqlStringCommand(“select RuleSet from Rules where Name=@Name”))

            {

                db.AddInParameter(cmd, “Name”, System.Data.DbType.String, this.RuleSetName);

                string ruleSet = (string)db.ExecuteScalar(cmd);

                this.DeserializeRuleSet(ruleSet);

            }

            this.ValidateRuleSet();

        }

 

        /// <summary>

        /// Deserializes a ruleset from the database into a RuleSet object.

        /// </summary>

        /// <param name=”ruleSetXmlDefinition”></param>

        private void DeserializeRuleSet(string ruleSetXmlDefinition)

        {

            if (!String.IsNullOrEmpty(ruleSetXmlDefinition))

            {

                StringReader stringReader = new StringReader(ruleSetXmlDefinition);

                XmlTextReader reader = new XmlTextReader(stringReader);

                this.RuleSet = Serializer.Deserialize(reader) as RuleSet;

            }

        }

 

        /// <summary>

        /// Executes the rule set on the given entity.

        /// </summary>

        public bool ExecuteRule()

        {

            if (null != ruleExecution)

            {

                try

                {

                    ruleSet.Execute(ruleExecution);

                }

                catch

                {

                    throw;

                }

                return true;

            }

            else

            {

                return false;

            }

        }

 

        /// <summary>

        /// Validates that the entity being processed contains the properties

        /// defined in the ruleset.

        /// </summary>

        private void ValidateRuleSet()

        {

            ruleValidation = new RuleValidation(this.entity.GetType(), null);

            if ((null != ruleValidation) && (!ruleSet.Validate(ruleValidation)))

            {

                string errors = “”;

                foreach (ValidationError validationError in ruleValidation.Errors)

                {

                    errors = errors + validationError.ErrorText + “\n”;

                }

                throw new Exception(errors);

            }

            else

            {

                ruleExecution = new RuleExecution(ruleValidation, this.entity);

            }

        }

 

    }

}

 

 

Like this article? kick it on DotNetKicks.com