SAP RFC calls and all that empty arrays.

Pretty often I have to do some SAP RFC calls (BAPIs) in my projects.
To retrieve a result structure you often have to pass an empty element of the same type in.
In BizTalk this is pretty easy with a Map. You just “connect” all the elements in the target schema to an existing root node and the transformation engine will do the rest for you creating the structure.

But when you have to create this structure in code you are pretty doomed creating all that empty arrays line by line.

Recently I got pretty tired of this, writing a web service calling a SAP BAPI.

So I wrote the following little code code snippet that does the work for me in a generic way.

private void CreateAllArrays(object o)
{
 o.GetType()
	.GetProperties(System.Reflection.BindingFlags.SetProperty
				| System.Reflection.BindingFlags.Public
				| System.Reflection.BindingFlags.Instance)
	.Where(p => p.PropertyType.IsArray)
	.ToList()
	.ForEach(p => p.SetValue(o, Array.CreateInstance(p.PropertyType.GetElementType(), 0), null));
}

Call the “CreateAllArrays” function passing in the object that has properties of type array of [AnyType] and it will create and set an empty array instance for every property found.

Please feel free to adopt and/or copy it for any kind of use.

TPL – Smoothing continuation a bit

Nachdem es auf dem .NET Open Space in Leipzig mit einem TPL Talk nicht geklappt hat am Sonntag, hab ich mir gedacht das ich an dieser Stelle hier in meinem Blog nochmal etwas nachlege zum Thema TPL (Task Parallel Library).
Ich beschäftige mich schon seit der CTP oder Betaphase mit der Task Parallel Library die damals noch unter etwas anderem Namen und in technisch etwas anderer Form sogar bedingt unter .NET 3.5 nutzbar war.
Als Microsoft kürzlich neue Features von C# 5.0 enthüllte auf der PDC2010 und die neuen Keywords await und async der Welt vorstellte sowie das dahinterstehende Konzept das auf der Technik der TPL aufbaut war ich hocherfreut zu sehen das Microsoft die TPL konsequent und nachhaltig weiterentwickeln wird.

Den Einstieg in das Thema TPL möchte ich mit ein paar Erleichterungen machen, die ich mir über die Zeit hinweg zugelegt habe. Das ganze erläutert an einem kleinen Beispiel wie es der eine oder andere sicher schon mal bei sich im Code gesehen hat.

Gehen wir von einem ganz simplen Szenario aus, in dem wir Kundendaten in ein Formular/View/Controller laden, filtern und anzeigen wollen. Sicher was nahezu alltägliches oder?

Mit der TPL würde man den Code vielleicht wie folgt schreiben:

      private void LoadAndDisplayCustomers()
      {   
         Task.Factory.StartNew(LoadCustomers)
                     .ContinueWith(t => FilterCustomersForDisplay())
                     .ContinueWith(t => DisplayCustomers());
      }

Wirklich schön ist das “Task-Parameter-Geschiebe” aber nicht, oder?

Mit einer kleinen Extensionmethod kann man sich das Leben schon einfacher machen und das ganze könnte wie folgt aussehen:

      public static Task ContinueWith(this Task task, Action action)
      {
         return task.ContinueWith(t => action);
      }
      private void LoadAndDisplayCustomers()
      {   
         Task.Factory.StartNew(LoadCustomers)
                     .ContinueWith(DisplayCustomers)
                     .ContinueWith(FilterCustomersForDisplay);
      }

Wenn man das Ganze zu einer “state-less” Verarbeitungskette (Eingabe-Verarbeitung-Ausgabe) machen möchte, dann wäre auch folgendes denkbar:
Extensionmethods:

      public static Task<T> ContinueWithResult<T>(this Task<T> task, Func<T, T> action)
      {
         return task.ContinueWith(t => action(t.Result));
      }

      public static Task ContinueWithAction<T>(this Task<T> task, Action<T> action)
      {
         return task.ContinueWith(t => action(t.Result));
      }

Implementierung:

      private void LoadAndDisplayCustomers()
      {         
         Task.Factory.StartNew<IEnumerable<Customer>>(LoadCustomers)
                     .ContinueWithResult(FilterCustomersForDisplay)
                     .ContinueWithAction(DisplayCustomers);
      }
      private static IEnumerable<Customer> LoadCustomers()
      {
         //  load and return customer data here...
      }

      private static IEnumerable<string> FilterCustomersForDisplay(IEnumerable<Customer> data)
      {
         // perform customer filtering here..
      }

      private static void DisplayCustomers(IEnumerable<Customer> data)
      {
         // display customers here ...
      }

Hoffe das diese Anregung zum Thema Continuation dem einen oder anderen weiterhilft.

Ich freue mich über Anregungen und Kritik zu diesem Thema, denn nichts ist so steif wie der “Monolog” eines Blogposts 🙂