Thursday, June 23, 2011

Build XML based Business Rule Engine in .NET 4 – Post 1 (Introduction and XML definition)

The requirement was simple that system should calculate Transaction Fee when distributing a product to external provider. We could have many providers and each have different rules to calculate Transaction Fee from sale price. The emphasis is on “Transaction Fee must be highly configurable”. How much *highly* configurable is contextual focus. It has to define limitation.
I thought of defining extensible lightweight XML rules so that end user can easily configure the rules or define new one of his choice. Later will develop a simple ‘Rule Engine’ to execute rules at runtime. I thought of ‘Forward Chaining’ where a distributor can have multiple rules to validate and each rule is combination of M conditions and N actions. If I could be able to have evaluated conditions - means to infer true or false at runtime then it will be achievement. Afterwards, I will go same way for actions. simple structure of a rule:

Rule => IF condition is true THEN execute action.

Let us define xml at first stage and use it at the end (its turn will not come until we are done other things for sure). 

<?xml version="1.0" encoding="utf-8" ?>
<Distributors>
<Amazon Key="Publizone_Price_Rule" Active="True">
  <Rule Name="transactionfee_is_5_percent">
    <Conditions LogicalOperation="AND">
      <Condition FieldName="NetProductPrice" Operation="GreaterOrEqual" Value="0"/>
    </Conditions>
    <Actions>
      <!--Calculate 5% of Net Price-->
      <Action Key="A1" FieldName="NetProductPrice" Operation="GreaterOrEqual" Data="5%" />
      <!--set value to TransactionFee property-->
      <Action FieldName="TransactionFee" Operation="EqualTo" Data="[A1]" />
    </Actions>
  </Rule>
  <!--If DRM is Watermarking (2) and TransactionFee < 4$ then TransactionFee = 4$-->
  <Rule Name="drm_is_watermarking">
    <Conditions LogicalOperation="AND">
      <Condition FieldName="DRM" Operation="Equals" Value="2"/>
      <Condition FieldName="TransactionFee" Operation="LessThan" Value="4"/>
    </Conditions>
    <Actions>
      <Action FieldName="TransactionFee" Operation="EqualTo" Value="4"/>
    </Actions>
  </Rule>
  <!--If DRM is hard DRMed (3) and TransactionFee < 8$  then TransactionFee = 8$-->
  <Rule Name="drm_is_digitaldrm">
    <Conditions LogicalOperation="AND">
      <Condition FieldName="DRM" Operation="Equals" Value="3"/>
      <Condition FieldName="TransactionFee" Operation="LessThan" Value="8"/>
    </Conditions>
    <Actions>
      <Action FieldName="TransactionFee" Operation="EqualTo" Value="8"/>
    </Actions>
  </Rule>
  <!--TransactionFee is always maximum 10$ -->
  <Rule Name="transactionfee_should_lessthan_10">
    <Conditions LogicalOperation="AND">
      <Condition FieldName="TransactionFee" Operation="GreaterThan" Value="10"/>
    </Conditions>
    <Actions>
      <Action FieldName="TransactionFee" Operation="EqualTo" Value="10"/>
    </Actions>
  </Rule>
</Amazon>

<iTune Key="iTune_Price_Rule" Active="True">
  <Rule Name="not_yet_defined">
  </Rule>
</iTune>
               
<GoogleBooks Key="GB_Price_Rule" Active="True">
  <Rule Name="not_yet_defined">
  </Rule>
</GoogleBooks>
</Distributors>

This is dummy a rule just as an example. Suppose Amazone will in their purchase return the following parts, per transaction.
1.       Exposed net price (i.e. the one that appears to the distributor)
2.       Transaction fee (5% of the above price, however min.  $2 by watermarked materials, min. $8 on hard DRM'ede materials, and always max. $10)
3.       "Genuine net price", ie. Exposed net price – Transaction fee

No rule definition for rest of the distributors like iTune and Google Books right now in XML.

In next post I will start building  following model (Keep it simple and stupid).

Want to read second post? click here to read>>


Your comments are greatly appreciated : 

Wednesday, June 22, 2011

Covariance and Contravariance support in .NET 4

According to Wikipedia,  in multilinear algebra and tensor analysis
"covariance and contravariance describe how the quantitative description of certain geometrical or physical entities changes when passing from one coordinate system to another"

Covariance By Example

If there is inheritance relationship, Employee base and Manager derived one, then there’s an implicit reference conversion from Manager to Employee
Manager → Employee
Then Covariance allows implicit conversion of generic types to the base types like
IEnumerable<Manager> → IEnumerable<Employee>
Since both arrows are in same direction means Covariance
Covariant in T: if the ordering of the constructed types follows the ordering of the generic type parameters

Contravariance By Example

Then Covariance allows implicit conversion of generic types to the derived types like
IComparable<Manager> ← IComparable<Employee>
Since both arrows are reversed means Contravariance
Covariant in T: if the ordering of the constructed types is reversed from the ordering of the generic type parameters

out keyword

Out keyword - readonly
the generic type parameter can only appear in output positions — read-only properties and method return values.
IEnumerable<Manager> ms = GetManagers();
IEnumerable<Employee> es = ms; //possible in c#4 only
T is covariant means you only get a Manager out of the sequence, and you never put one in

      in keyword

In keyword - writeonly
The generic type parameter can only be used in input positions — write-only properties and method non-ref and non-out parameters.
IEnumerable<Manager> ms = GetManagers();
IEnumerable<Employee> es = ms; //possible in c#4 only
Vs.
IComparable<Employee> ec = GetEmployeeComparer();
IComparable<Manager> mc = ec; //possible in c#4 only
T is contravariant means because a manager is an employee, putting a manager in EmployeeComparer should work, and it does.

To get more details please download following presentation:

Wednesday, June 8, 2011

C#: dynamic support in .NET 4

With C# 4.0, there is a new keyword: dynamic. This allows you to use an object without defining its type at compile time. It tells compiler – variable type is unknown until runtime. dynamic can be thought of as a special version of the type object that is “suspending belief

"dynamic is a static type that bypasses static type checking"

This allows you for example to call dynamic objects using the DLR (Dynamic Language Runtime).
Dynamic Objects could be one of following:
- a javascript method
- COM interop
- dynamic language (Ironpython, Ironruby) object
- HTML DOM in silverlight
- Object Implemetating IDynamicMetaObjectProvider

To understand dynamic in details, you can download my presentation from following link.

PPT DOWNLOAD LINK:
http://cid-61065223cd826e76.office.live.com/view.aspx/Public/Presentations/2.Dynamic.pptx


Comments/feedback are most welcome here.



Sunday, June 5, 2011

Planning Full Migration from VSS to TFS2010

If you are thinking of Full Migration (with History) from VSS to TFS 2010, you must have a plan. Depending on your user security isolations, departments having different needs, dealing with different product lines, two teams interested to adopt different methodology/process template (like MSF Agile document 5.0 vs MSF CMMI document 5.0) and other concerning factor.

The idea starts planning for "Team Project Collections" TPCs. Ideally there should be one TPC in an organization unless two different departments have different target users with different access matrices. Then comes "Team Project" TP. Different Product lines (like Visual Studio vs Office) should have different TPs because each will have different set of target users with specific access needs. Teams with conceptually isolated projects should be in separate TPs because both will  have different iterations, milestones, artefacts and people involved. Single TP will have single Check-out, check-in lock, Check-in policy. If two teams have different requirements of policy like one wants "Allow Multiple Users to check-out" and other team not allows this then both should be separated. Here is a basic level presentation on TFS2010 available for download.

http://cid-61065223cd826e76.office.live.com/view.aspx/Public/Presentations/TFS2010PlanningHowto.pptx

Saturday, April 16, 2011

IntelliSense error creating simple unmanaged MFC DLL in VS2010

I am using VS2010. Sometimes (not always) I create an MFC DLL and choosing type ‘Regular DLL using Shared MFC DLL’ and just compile the solution. I get an intelligence error.  Here is exact error I face
IntelliSense: #error directive: Please use the /MD switch for _AFXDLL builds        c:\program files (x86)\microsoft visual studio 10.0\vc\atlmfc\include\afxver_.h                81
After searching it I reached following link:
Please try the following:
  1. Right-click the Project.
  2. Go to Config Properties->C/C++-> Code Gen ->. Double-click "Runtime Library" and set to "Multi-threaded Debug DLL (/MDd)" . If this value already appears to be set, make sure it is by electing it again (it should then appear as bold).
  3. Click OK.

Wednesday, April 13, 2011

Develop an unmanaged DLL (MFC DLL) in VS2010 and Import in managed C# Project



Yesterday I had a need to write a wrapper for a 3rd party ActiveX control (ATL COM dll in VC6). The purpose is to write a wrapper and call from C#. The motive is due to the way ATL ActiveX was developed, there was a design issue in marshalling and when used directly from c# not return the proper results. To cut it short, I was interested to write its wrapper. 
It has been five years; I have not touched COM and VC++ due to the focus in C# majorly. But I was interested to write a wrapper and decided to develop it in VS2010. Question was how to start?
Yes, I should start creating MFC DLL in VS2010 and export a method/calss and call the function from C#.
I decided to create a MFC DLL and choosing type ‘Regular DLL using Shared MFC DLL’. The output produced by this option (dynamically linked) is a small DLL in size. The statically linked DLLs will be of larger size, as they are built with the whole MFC libraries within themselves.  
A MFC Dll can provide/export with functions, variable values, constants and classes. I focused on exporting a function, and then whole class afterwards. 
Then I added two files Util.h and Util.cpp in the project and wrote a sample function ‘Add’. Here is header file single line of code.


extern "C" __declspec(dllexport) int Add (int a, int b);

__declspec(dllexport)'s purpose is to add the "export directive" to the method.  extern "C" is meant to be recognized by a C++ compiler and to notify the compiler that the noted function is compiled in C style.
Here is Utils.cpp code:


#include "stdafx.h"
#include "Util.h"

 __declspec(dllexport) int Add (int a, int b)
{
       return a + b;
}

Compiled the MFC DLL project and it produced TTSUnmanagedWrapper.dll and TTSUnmanagedWrapper.lib in debug folder. There are two debug folders one under project sub folder and other at project root.  Please target the right one mentioned in Output window during compilation proves in VS2010.
Oks now I have MFC DLL available, Question is how to import this Unmanaged DLL to C#?
Crate a new C# Windows Form application and create a new class as follows


using System;
using System.Runtime.InteropServices;

namespace WindowClient
{
    public class NativeDLLHelper
    {

        [DllImport( @"D:\TTSUnmanagedWrapper\Debug\TTSUnmanagedWrapper.dll",
                    EntryPoint = "Add",
                    CallingConvention = CallingConvention.Cdecl)]
        public static extern int Add(int aa, int bb);
   
    }
}

Calling convention CallingConvention.Cdecl means DLL method is in C Calling convention.
And call the method anywhere in C# code like this:

int c = NativeDLLHelper.Add(2, 7);

Next Step: How to export a class instead of single function

Define a new class in Util.h
class __declspec(dllexport) DLLWrapper{
private:

public:
       DLLWrapper();
        
       int DoAdd(int x,int y);

};

And in Util.cpp write following code:

DLLWrapper::DLLWrapper()
 {

 }

int DLLWrapper::DoAdd(int x, int y)
{
       return x+y;
}

Compile the MFC DLL again. 
Now come to NativeDLLHelper class in C# project.

[DllImport( @"D:\TTSUnmanagedWrapper\Debug\TTSUnmanagedWrapper.dll",
                    EntryPoint = "?DoAdd@DLLWrapper@@QAEHHH@Z",
                    CallingConvention = CallingConvention.Winapi )]
        public static extern int DoAdd(int aa, int bb);

I defined the entry point above. It is where ‘Dependency Walker” really helped. 



And Calling convention CallingConvention. Winapi means DLL method is in C++ Calling convention. 
And call the method anywhere in C# code like this:

int d = NativeDLLHelper.DoAdd(3, 5);

That’s it :)

Monday, March 14, 2011

FxCop 10.0 code analysis results are not shown in CCNET Build Report

Situation:
I am using cruise Control .NET (V1.5.7256.1) with TFS 2008 and VS2010.  Integration is such that for each checkin CCNet gets latest version using sourcecontrol type="vsts", and build with MSBuild. My solution contains single project file, I have enabled option “Code Analysis on Build” from Code Analysis tab in VS2010 and selected “Microsoft Minimum Recommended Rules”.
Now FxCop (V10.0) obviously run and generate “[ProjectName].exe.CodeAnalysisLog.xml” file in bin\debug folder when build is successful. Using CC merge tool, I can integrate the results to BuildLog xml files. Everything is working upto this point.  I can see build XML and Fxcop report is integrated nicely.
Problem Statement: when I see build report in dash board, no Fxcop results are displayed. How to identify and integrate FxCop 10.0 xsl to display the results on HTML report is the issue.

Resolution:
I googled for some time and found, CCNet does support FxCop version 1.36 and not later than that. When I browsed to “C:\Program Files\CruiseControl.NET\webdashboard\xsl” folder, I can see “fxcop-report_1_36.xsl” file. So at another place, there was a clue to generate xsl for FxCop 10.0. Very simple, just create a copy of fxcop-report_1_36.xsl with new name “fxcop-report_10_0.xsl” and replace version number in new created file to “10.0”. Here is original code need to replace:
<xsl:variable name="fxcop.root" select="//FxCopReport[@Version = '1.36']" />
 - to -
<xsl:variable name="fxcop.root" select="//FxCopReport[@Version = '10.0']" />
Still no report is coming under Build Log
Then I reached to the conclusion, I should edit dashboard.config to under ccnet website in IIS, so I opened it and append fxcop10 xsl path as follows:
   <buildPlugins>
      <buildReportBuildPlugin>
        <xslFileNames>
          <xslFile>xsl\header.xsl</xslFile>
          <xslFile>xsl\modifications.xsl</xslFile>
          <xslFile>xsl\fxcop-report_10_0.xsl</xslFile>
        </xslFileNames>
      </buildReportBuildPlugin>

I saved the changes, Restarted CCNET service under SCM, then Reset IIS using command line. When I accessed the page, I can see the Build Report with Fxcop 10.0 static code analysis. Here is a snap:

 Great, isn't it :)