Skip Navigation Links Home Blogs

cubido > Blogs > Posts > Custom C# Functions for the BizTalk 2004 Business Rule Composer
October 16
Custom C# Functions for the BizTalk 2004 Business Rule Composer

The target (for this example) is to create an custom component that changes a date value to the next weekday (based on a stored function in a database). This component is used in a rule which should unter certain circumstances assign only weekdays to a date.

 

To achieve this on has first to imlement the actual class which mapps a date to the next weekday. In my case the next weekday is calculated in an stored function defined in our application database.

using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using System.Diagnostics;
namespace Cubido.BizTalk.Tools
{
 public class DateTool
 {
  public DateTool()
  {
   if(!EventLog.SourceExists("Cubido.BizTalk.Tools"))
    EventLog.CreateEventSource("Cubido.BizTalk.Tools", "Cubido.BizTalk.Tools");
  }
  public string NextWeekDayString(DateTime date, string calendarId, string connectString)
  {
   try
   {
    SqlConnection con = new SqlConnection(connectString);
    con.Open();
    SqlCommand cmd = con.CreateCommand();
    cmd.CommandText = "SET DATEFIRST 1; SELECT dbo.JuxtaposedWorkdayAfter(@CalendarID, @Date)";
    cmd.Parameters.Add("@CalendarID", SqlDbType.VarChar, 12).Value = calendarId;
    cmd.Parameters.Add("@Date", SqlDbType.DateTime).Value = date;
    date = (DateTime) cmd.ExecuteScalar();
    con.Close();
   }
   catch(Exception e)
   {
    EventLog eventLog = new EventLog();
    eventLog.Source = "Cubido.BizTalk.Tools";
    eventLog.WriteEntry(e.ToString(), EventLogEntryType.Error);
   }
   string curdate = date.ToString("yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture);
   string curtime = date.ToString("T",System.Globalization.CultureInfo.InvariantCulture);
   return curdate + "T" + curtime + ".000";
  }
 }
}

A few thing are notable about this piece of code:

  • the function NextWeekDayString returns a String and not a DateTime. Returning a DateTime resulted in some errors which I could not follow and with String as return value it works like a charm. The string representation of the date value is such that the date is recognized by the Microsoft SqlServer as valid date.
  • The Parameter calendarId and connectString are just my way to specify the neccessary type of calendar used (the application allowes different calendars in different situations) and the connect string to our applications database. Both values are defined in the vocabulary as constants.

The second piece of code is not so ovious - but it is needed nevertheless. It's just a class needed by the rule composer for manageing the fact.

using System;

using Microsoft.RuleEngine;

namespace Cubido.BizTalk.Tools
{
 ///
 /// Summary description for FactCreator.
 ///
 public class FactCreator : IFactCreator
 {
  public object[] CreateFacts(RuleSetInfo rsi)
  {
   object[] o = new object[1];
   o[0] = new Cubido.BizTalk.Tools.DateTool();
   return o;
  }
  public Type[] GetFactTypes(RuleSetInfo rsi)
  {
   Type[] t = new Type[1];
   t[0] = new Cubido.BizTalk.Tools.DateTool().GetType();
   return t;
  }
 }
}

The interface FactCreator (implemented in an Assembly found in '...\Program Files\Microsoft BizTalk Server 2004\Microsoft.RuleEngine.dll') has to be imlemented and the content of the object array retured matches all the functions that should be accessed from the Business Rule Composer.

The assembly (or assemblies if you have more of them) have to reside in the global assembly cache. For me it was usefull to set the version of the assembly to '1.0.0.0' (in the AssemblyInfo.cs) and define a post build step which removes the old assembly and adds the new on from/to the GAC.

Having come so far the C# programming is over, the component can be used within the Business Rule Composer. To do so one must add the component in the Fact Explorer. After that it can be used within any rule either in the Condition part or in the Then part.

If you do some testing within the Business Rule Composer you have to add the Assembly with the class implementing the IFactCreator interface to the fact creators in the Test Policy dialog.

When the Rule is accessed from an orchestration, the class which implements the custom function has to be assigned to a variable (Variables -> New Variable) and provided as parameter in the Call Rule shape. 

Comments

Sorry - privat

Rainer, kannst Du mich bitte anmailen?<br><br>Thomas Wiesinger (HTL 1986)<br>tomhtl@wiesinger.org<br>
CUBIDO\p.kirschnerNo presence information on 3/17/2010 10:01 AM

Re: Custom C# Functions for the BizTalk 2004 Business Rule Composer

Can we add two strings inside the Biz Talk Rule Composer
CUBIDO\p.kirschnerNo presence information on 3/17/2010 10:01 AM

Re: Custom C# Functions for the BizTalk 2004 Business Rule Composer

yes you can.....by having 2 variables of type string
CUBIDO\p.kirschnerNo presence information on 3/17/2010 10:01 AM

Re: Custom C# Functions for the BizTalk 2004 Business Rule Composer

Do we have to "call" FactCreator in some way in the rule?
CUBIDO\p.kirschnerNo presence information on 3/17/2010 10:01 AM

Re: Custom C# Functions for the BizTalk 2004 Business Rule Composer

Do we have to "call" FactCreator in some way in the rule?
CUBIDO\p.kirschnerNo presence information on 3/17/2010 10:01 AM

Re: Custom C# Functions for the BizTalk 2004 Business Rule Composer

Do we have to "call" FactCreator in some way in the rule?
CUBIDO\p.kirschnerNo presence information on 3/17/2010 10:01 AM

Re: Custom C# Functions for the BizTalk 2004 Business Rule Composer

Do we have to "call" FactCreator in some way in the rule?
CUBIDO\p.kirschnerNo presence information on 3/17/2010 10:01 AM

Re: Custom C# Functions for the BizTalk 2004 Business Rule Composer

You rock! - This explanation and sample provided me with exactly what I needed and couldn't find from Microsoft.  Since I wasn't submitting a fact, I never thought I might need IFactCreator - but you are right: I do.<br><br>Thank you very much.<br><br>(and for PA: no, you dont - it just needs to be there)
CUBIDO\p.kirschnerNo presence information on 3/17/2010 10:01 AM

Re: Custom C# Functions for the BizTalk 2004 Business Rule Composer

Sorry for multiple posting by the way.<br><br>I have now developed my own custom class, and made a rule using the method from it. When test the rule, it seems fine. But when actually running it from the application, the rule will not fire when I use this method from the custom .net component! So here is some code: (hope for some help...)<br><br> public class TimeDifference : Microsoft.RuleEngine.IFactCreator<br>    {<br>        public TimeDifference()<br>        {<br><br>        }<br>        public int StringToInt(string value)<br>        {<br>            return Int32.Parse(value);<br>        }<br><br> #region IFactCreator Members<br><br>        public object[] CreateFacts(RuleSetInfo ruleSetInfo)<br>        {<br>            return new object[] { new TimeDifference() };<br>        }<br>        public Type[] GetFactTypes(RuleSetInfo ruleSetInfo)<br>        {<br>            Type converterType = this.GetType();<br>            return new Type[] {converterType };<br>        }       <br><br>        #endregion<br>    }<br><br>Here is my simple rule:<br><br>//in the if panel<br>TimeDifference.StringToInt(3) is less than or equal to 10<br><br>Using this will make the rule not fire. Removing this and use other method from not custom .net component will work. <br><br>By the way, I am testing on Biztalk 2006 R2
CUBIDO\p.kirschnerNo presence information on 3/17/2010 10:01 AM

Re: Custom C# Functions for the BizTalk 2004 Business Rule Composer

GLT10a02peng24<br>nice article, i got good information, thanks for posting..<a href="http://www.chanel-luxury.com"><b>chanel handbags</b></a>
CUBIDO\p.kirschnerNo presence information on 3/17/2010 10:01 AM
1 - 10Next
 

 Add Comment

 
Titel  
Your Name:  
Your Comment:  
Your EMail:  
*