CodeRush Love…

I’ve recently acquired a CodeRush license
for my personal use, and all I can say is … I LOVE CODERUSH!

You may be asking, “Why do you love CodeRush, Tim?” Here’s why. By using the following
sequence :

C Space P E R S O N
Click to the end of constructor block
Enter P S Space F I R S T N A M E
Click to the end of the property block
Enter P S Space L A S T N A M E
Click on class name
Ctrl-C
Click outside of the class
coll Space

Produces all of the following code:

    public class Person
    {
        
public Person(string myFileName)
        {

        }
        private string _FirstName;
        
public string FirstName
        {
            
get
            {
                
return _FirstName;
            }
            
set
            {
                _FirstName
=
value;
            }
        }
        
private string _LastName;
        
public string LastName
        {
            
get
            {
                
return _LastName;
            }
            
set
            {
                _LastName
=
value;
            }
        }
    }

    public class PersonCollection : CollectionBase
    {
        
//
public methods…
        #region Add
        
public int Add(Person person)
        {
            
return List.Add(person);
        }
        #endregion
        #region
IndexOf
        
public int IndexOf(Person person)
        {
            
for (int i
= 0; i < List.Count; i++)
                
if (this[i]
== person)    
// Found it
                    return i;
            
return -1;
        }
        #endregion
        #region
Insert
        
public void Insert(int index, Person person)
        {
            List.Insert(index,
person);
        }
        #endregion
        #region
Remove
        
public void Remove(Person person)
        {
            List.Remove(person);
        }
        #endregion
        #region
Find
        
//
TODO: If desired, change parameters to Find method to search based on a property of
Person.
        public Person Find(Person person)
        {
            
foreach (Person lPersonItem in this)
                
if (lPersonItem
== person)    
// Found it
                    return lPersonItem;
            
return null;    //
Not found
        }
        #endregion
        #region
Contains
        
//
TODO: If you changed the parameters to Find (above), change them here as well.
        public bool Contains(Person person)
        {
            
return (Find(person)
!=
null);
        }
        #endregion

        //
public properties…
        #region this[int
aIndex]
        
public Person this[int index]
        {
            
get
            {
                
return (Person)List[index];
            }
            
set
            {
                List[index]
=
value;
            }
        }
        #endregion
    }

Programmatically Create Windows Workflow Rules

I am currently working with a client that is evaluating the Windows Workflow Rules Engine.  One of their requirements is that they need to be able to create the rules programmatically through their own application.  First we looked at the ability to host the Windows Workflow rules dialog boxes in our application.  We can accomplish this through the RuleSetDialog object and the RuleConditionDialog object.  Second we looked at how we could create our own UI and programmatically create the rules through an API.  Based on the requirement of the application they have decided to use their own UI.  So, the search began on how we were going to create these rules.


 


The Workflow Rules Engine API works through the CodeDom system.  This makes a lot of sense since we are using code to create code – which is exactly what CodeDom was designed for.


 


I have used a sample fictitious rule that represents the type of rule that will be created through the UI.  The rule we need to create (and the one used in the example below) is a rule that checks the model and year of a car along with the gas mileage and assigns a surcharge, if necessary. 


 


In looking at the code below I have set up private variables to hold our data.  This could have easily been a separate object (and will be in real life).  Once I have my variables I need to setup the CodeDom objects which will reference the variables that I will be using in my rules. 


 


The CodeDom objects that are supported in the rules object model are:




  • CodeThisReferenceExpression



  • CodeArrayIndexerExpression



  • CodeAssignStatement



  • CodeBinaryOperatorExpression



  • CodeCastExpression



  • CodeDirectionExpression



  • CodeExpressionStatement



  • CodeFieldReferenceExpression



  • CodeIndexerExpression



  • CodeMethodInvokeExpression



  • CodeMethodReferenceExpression



  • CodePrimitiveExpression



  • CodePropertyReferenceExpression



  • CodeTypeReference



  • CodeTypeReferenceExpression


 


Next, I start the rule creation code.  I create a RuleSet object which I will add Rule objects to.  After I create the Rule object then I create the conditions which will be added to the rule using the Rule.Condition property(handing it a RuleExpressCondition object).  After that I will add the action using the Rule.ThenAction.Add Method (handing it a RuleStatementAction object).  I can also add the Else action using the Rule.ElseActions.Add method.  Before I can add the condition I need to create the code to represent the predicate parts that will be added to the condition.  In the code this can be seen starting with the code to create the predicate for GasMileage.  I create a CodeBinaryOperatorExpression object and then using the Left, Operator and Right properties to assembly the predicate.  I continue this for each of the predicates I will need for this rule (in this case there are 3).  I have shown in the code how to compare against an integer (with the GasMileage predicate), against a string (with the ModelYear predicate) as well as against an Enum type (with the CarCategory predicate).  These predicates also show how to use the CodeBinaryOperatorType object with both the .ValueEquality and .LessThan operators.  An interesting find is that there is no inequality operator.  To find inequality you need to create the syntax as (CarCategory == “Sports”) == false.


 


Once I have created the predicates that represent each of the parts of my rule I then need to join the predicates and create the condition which will be passed to a RuleExpressionCondition object.  As seen in the code below I take the first two predicates; the ruleGasMileageTest object and using a BooleanAnd operator join to the ruleCarCategoryTest object.  If I only had two predicates I would be done and could add the condition object to the rule (carChargeRule).  Since I had three predicates I need to take the condition object created from the joining of the first two predicates and join them to the third predicate (ruleModelYearTest) to create the final condition (ruleCondition2) which will be added to the rule.


 


At this point we have the ‘if’ portion of the rule complete.  We now need to create the ‘then’ portion.  This is accomplished using the Rule.ThenAction.Add method as seen at the bottom of the code.


 


After you have looked at the code make sure to look at the image of the locals window which follows the code.  This screen shot shows the rules code that all of this CodeDom code created.


 


 


 


public class ……


{


//Object Items


private string CarName = “Jaguar”;


private string CarModel = “XK SLE”;


private string ModelYear = “2009”;


private CarCategory carCategory = CarCategory.SportsCar;


private int GasMileage = 12;


private double SurchargeRate = 0;


 


 


private void BuildRuleSet()


{



RuleSet surchargeRuleSet = new RuleSet(“SurchargeRuleSet”);


 


// Define property and activity reference expressions through CodeDom functionality


CodeThisReferenceExpression thisRef = new CodeThisReferenceExpression();


CodeFieldReferenceExpression CarNameRef = new CodeFieldReferenceExpression(thisRef, “CarName”);


CodeFieldReferenceExpression CarCategoryRef = new CodeFieldReferenceExpression(thisRef, “carCategory”);


CodeTypeReferenceExpression CategoryEnumRef = new CodeTypeReferenceExpression(typeof(CarCategory));


CodeFieldReferenceExpression ModelYearRef = new CodeFieldReferenceExpression(thisRef, “ModelYear”);


CodeFieldReferenceExpression SurchargeRef = new CodeFieldReferenceExpression(thisRef, “SurchargeRate”);


CodeFieldReferenceExpression GasMileageRef = new CodeFieldReferenceExpression(thisRef, “GasMileage”);


 


// IF GasMileage < 15 AND CarCategory = Sports AND ModelYear = 2009


// THEN Surcharge = $500


Rule carChargeRule = new Rule(“CarChargeRule”);


surchargeRuleSet.Rules.Add(carChargeRule);


 


// define first predicate: GasMileage < 15


CodeBinaryOperatorExpression ruleGasMileageTest = new CodeBinaryOperatorExpression();


ruleGasMileageTest.Left = GasMileageRef;


ruleGasMileageTest.Operator = CodeBinaryOperatorType.LessThan;


ruleGasMileageTest.Right = new CodePrimitiveExpression(15);


 


// define second predicate: CarCategory = Sports


CodeBinaryOperatorExpression ruleCarCategoryTest = new CodeBinaryOperatorExpression();


ruleCarCategoryTest.Left = CarCategoryRef;


ruleCarCategoryTest.Operator = CodeBinaryOperatorType.ValueEquality;


ruleCarCategoryTest.Right = new CodeFieldReferenceExpression(CategoryEnumRef, “SportsCar”);


 


// define third predicate: ModelYear = 2009


CodeBinaryOperatorExpression ruleModelYearTest = new CodeBinaryOperatorExpression();


ruleModelYearTest.Left = ModelYearRef;


ruleModelYearTest.Operator = CodeBinaryOperatorType.ValueEquality;


ruleModelYearTest.Right = new CodePrimitiveExpression(“2009”);


 


// join the first two predicates into a single condition


CodeBinaryOperatorExpression ruleCondition = new CodeBinaryOperatorExpression();


ruleCondition.Left = ruleGasMileageTest;


ruleCondition.Operator = CodeBinaryOperatorType.BooleanAnd;


ruleCondition.Right = ruleCarCategoryTest;


 


// join the third predicate into the condition


CodeBinaryOperatorExpression ruleCondition2 = new CodeBinaryOperatorExpression();


ruleCondition2.Left = ruleCondition;


ruleCondition2.Operator = CodeBinaryOperatorType.BooleanAnd;


ruleCondition2.Right = ruleModelYearTest;


 


carChargeRule.Condition = new RuleExpressionCondition(ruleCondition2);


 


// add the action: Surcharge = 500


CodeAssignStatement ruleSurchargeAction = new CodeAssignStatement(SurchargeRef, new CodePrimitiveExpression(500));


carChargeRule.ThenActions.Add(new RuleStatementAction(ruleSurchargeAction));


 


// Add the ruleset


RuleDefinitions ruleDef = new RuleDefinitions();


ruleDef.RuleSets.Add(surchargeRuleSet);


 


// Set the RuleDefinitions on the workflow


this.SetValue(RuleDefinitions.RuleDefinitionsProperty, ruleDef);


}


 


public enum CarCategory


{



SportsCar = 0,


Sedan = 1,


SUV = 2,


…….


}


 


 



 

BTSDEPLOY on a remote BiztalkMgmtDb database

Do you think you can use BTSDeploy on a remote BiztalkMgmtDb database server?

I thought it will after looking at its parameter list, it takes a database server name and managment database name and an XML port configuration file as arguments. So, it sounded very normal for me to take it for granted we can IMPORT/EXPORT stuff into remote Biztalk server (or groups) using the BTSDEPLOY command.

Example:
BTSDEPLOY EXPORT SERVER=ACCD12WS229 DATABASE=BiztalkMgmtDb BINDING=c:\ports.xml UNBOUNDPORTS

We architected everything based on this assumption.The idea of our project is to control multiple biztalk environments (groups) from a single web application. The project I’m working on is relatively of big scale where we have around 10 different Biztalk server groups each with 4 Biztalk servers + all those additional SQL servers, Clusters blau, blau.

As a developer I was working on my workstation specifying my local workstation name as server and BiztalkMgmtDb as database parameter. For quite long time we didn’t hit any problems. Once in a while we connected to some other developer boxes remotely to do some testing and everything worked seamlessly. (Yes! it worked seamlessly connecting to a remote biztalk server).

Hang on before you start cursing, why is this post then?!! All our problems started when we deployed our solution into the module testing environment. Suddenly we saw this error comming up

Access Denied. Microsoft.Adapter..WSE.dll

There are so many attributes which can go wrong and produce this error, some of them we considered.
1. It’s a ASP.NET web applicaiton, so some of the credentials may not be correct. (We used application pool running under specified Biztalk account).
2. You are accessing a remote Biztalk Database server, where some SSO bits involved. So, again some credentials may not be correct.
3. There could be some problem in MSDTC between the ASP.NET server and reomote DB server

etc,etc…we can think of so many attributes because of the distributed nature of Biztalk itself and thing what we were trying to achive.

Luckily, this error popped up on one of the developer box as well, where he was using one of our inbuild custom adapters. Then we came to a conclusion, this problem occurs only for biztalk servers(groups) where some custom adapters are deployed (BTW, WSE adapter is also an addon adapter on top of Biztalk base build).

If you deploy the same adapter in the main server** and run the command against a remote server, it IMPORTED/EXPORTED successfully. Wow! so what’s going on underneath the scene.

Here you go. Thanks to Microsoft folks Angus foreman and his upline MS staff at Redmond for making us understand what going on beneath the scene.

When you EXPORT configuration from BiztalkMgmtDb, the result set comes as a big blob data to the main Biztalk Server** in an encrypted form. Then the main server** parse the result with the help of adapters deployed in the main server**, from where it gets all the design time parameters of the adapters from the registry and generates the output port configuration xml file. If the adapters are not present in the main server** but the data is present in the blob then there is a mismatch and BTSDEPLOY throws Access denied error. We wouldn’t have found out this error or the functionality behind if there were no custom adapters.

Then, we did some work around to fix the problem, using web services and stuff. Huh! this post is already to long.

**(from where the BTSDEPLOY command is executed)

SharePoint Community Center

Summer is just around the corner, and it’s time to hit the local Parks and Rec room to shoot some stick pool and play ping pong and… configure (your choice) SharePoint Portal Server 2003 or SharePoint Server 2007 Beta 2.  Beta 2 will release to the public in a few weeks (less?), and all of your friends will be working with it before you know it.  You can meet up with them at the newly launched/refreshed SharePoint Community Center page here: http://www.microsoft.com/sharepoint/community.mspx.  See you online…

ESB Adoption: lighting the road ahead

When building an infrastructure-type system like an ESB, often the architects and developers tend to naturally focus on the technical challenges. Ultimately, they reach a point where the code is done, functionality is complete, all unit tests pass, and everything has been deployed into production. Then an email goes out letting everyone know that the project goals have been met. We’re done, right?


Most of the time, I would say no, we are not done. Infrastructure services generally are not a case of “if you build it they will come”? Maybe, but not likely. Developers are creatures of habit. They get used to doing something a certain way, and stick to it. When deploying something like an ESB, you need to educate them. You’re deploying powerful capabilities, but the team needs to understand the implications and benefits in order to ensure adoption. With adoption, organizational benefits will be realized. Without adoption, you’ve just wasted a lot of effort.


For the project I am on, as part of our rollout, we are doing “brown bags” where people can learn about what the ESB is, and what it means to them and their applications. This is a great start and a great way to “socialize” the technology, and raise organizational awareness of infrastructure services.


However, I felt the need to provide developers with something more, something that would guide them and ease their adoption of ESB capabilities. Something that would continue on after I rolled off the project. It was this thinking that lead to the Core Engine SDK.


The Core Engine SDK will consist of:


– a naming conventions document
– sample programs
– a “Developer’s Guide to the ESB Core Engine” (more details later in this post)


Naming Conventions: what’s in a name?
Experienced BizTalk developers do all their work in virtual machines. In that isolated world, it doesn’t matter what you name things, if there are collisions or conflicts you’ll be able to figure them out. You’re likely only working with a small amount of artifacts. However, once you deploy into staging/production environments, your solution enters into a shared environment. In a large organization with a lot of BizTalk artifacts, a structured naming convention is required in order to ease management of the environments. Without one, chaos will ensue.


So, I created a naming conventions document that is based on best practices gleaned from past projects and other projects done by people I know. The resulting naming conventions document something that developers need to follow. In fact, although it may seem draconian, they MUST adhere to it or their application will not get deployed. Compliance to the naming conventions is a key part of the “on-boarding process” we will be implementing. I will do a future post on what I see this process as being.


Samples: show me how it’s done
The sample programs are examples of how the ESB Core Engine capabilities may be used in a solution. Knowing that the target audience will be BizTalk developers, these samples will follow the model of the BizTalk SDK in that they will have setup/cleanup batch files to quickly get a sample running, and to quickly remove it. We are creating a business scenario that will be used across all the samples, the idea being we want a readily understood business-specific scenario so developers don’t waste cycles trying to grasp some made-up business need, and focus instead on the techniques being shown. Our goal is that the samples will be very function-focused, each sample will address one (and where possible only one) aspect of something an application may need to do with the ESB.


As an example, I am writing “The Ultimate Handler for ESB Exceptions” (future post coming here, it is sooooo cool), but the first SDK sample will be how to write a highly targeted exception handler. This will show developers how they can incorporate our exception handling mechanism into their applications.


The Developer’s Guide: tell me what I need to know.
A project the scope of the ESB I am on will of course generate a bazillion documents and diagrams. However, in my opinion, one of the key documents, and in fact one of the keys to the success of the whole project, is the document I created for the developers and architects charged with building applications that will run on the ESB. I can’t post the document (of course!), but I thought posting the table of contents would at least show the sections that I felt it was important to address. This is not documentation for the ESB itself, that’s a whole other document aimed at developers who will be maintaining and extending the ESB. This documentation is targeted at the *users* (developers) of the ESB.


In the following listing, I have replaced the client’s name with “xxxxx”. I have left page numbers in so you get a sense of depth.


Introduction 4
– Overview 4
– Target Audience 4
– Revision History 4
Introduction to the xxxxx ESB 5
– What is it? 5
Introduction to the ESB Core Engine 6
– What is it? 6
– How is it architected? 6
– How should you architect your BizTalk solutions? 7
Working with the Iteration 1 xxxxx ESB Core Engine 8
– Functionality Provided 8
– Scenarios 9
Getting Started with the Core Engine 11
– How it works 11
– Installing the ESB in your virtual machine 11
– Installing the CtxSetGeneric Pipeline Component 12
– Installing the JMS Pipeline Components 13
Developing BizTalk Solutions with the Core Engine 14
– Naming Conventions and Rules 14
– The ESB On-Ramp: Receiving and Creating Messages for ESB Processing 14
— Using the CtxSetGeneric Pipeline Component 15
— Using a Property Schema 15
— Getting access to ESB Metadata Properties by Assembly Reference 17
– The ESB Off-Ramp: Creating Subscribers 19
– Working with JMS Messages over MQ Series 21
Dynamic Mapping 23
– Overview 23
– Order of Selection 23
– Dynamic Mapping Errors 23
Exception Handling 24
– Overview 24
– Core Engine Exception Handling 24
– Creating Custom Exception Handlers 24
Core Engine Roadmap 26
– Overview of Iteration 2 and beyond 26
– Protocol Hops 26
– Defined Processing Steps 26
– Increased Map Selection Capabilities 26
– Enhanced Exception Handling 26
– “Per instance” Receive Location Control 26
Appendix 1: ESB Metadata Schema 27
Appendix 2: Exception Message Schema 28


Many developers hate writing docs, but if you’re on an ESB project, the table of contents shown above could serve as a valuable guide to creating an effective and easily understood way to get developers up to speed and using the ESB.


Now all you have to do i