Saturday, January 26, 2013

JavaScript mini TPL library: RunAsync

Having learned about HTML5 Web Worker functionality, and that most of the modern browsers implement it, together with the File API BlobBuilder capability I thought about building a library that resembles C#'s Task Parallel Library, allowing JavaScript to be executed in a background thread, but at the same time, adding the ability to dispatch execution to the UI thread and also invoke callbacks and continuations to a "task". I figured the dispatcher functionality was important since usually whatever is executed in the background can/probably will need to interact with the UI while executing. Also this opens a door to use UI frameworks such as jQuery and/or any other DOM access. The problem of passing state while dispatching to the UI thread still exists, but it's on my queue to be solved.

Do check GitHub's page: https://github.com/ricmrodrigues/runasync 

Usage:

Task:
Task.run(function([parameters]) { } [, Array parameters]) returns Promise
Dispatch execution to the UI thread (from within a Task.run or continueWith function callback):
dispatch(function() {})
Promise:
//'when' executes in the UI thread, immediately after the background thread finishes
when(function([parameters]) { }) return Promise
//'continueWith' spins up a new task with the callback provided
continueWith(function([parameters]) { }) returns Promise

Performance:

Running code synchronouslyhttp://jsfiddle.net/UejYX/3/
Example:
for (var x=1;x<=3;x++) {
    (function(idx) {
        var task = Task.run(function(idx) {                
            var response = 0,
                max = (89000000*(idx*3));

            dispatch(function() {
                //do some DOM manipulation that gets executed in the UI thread
            });         

            for (var i=0;i<max;i++) {
                i++;
                if (i === max - 1) response = i;        
            }
            return response;
        }, [idx]);

        task.when(function(value) {
            console.log("executed from UI thread");
        });

        task.continueWith(function(value) {
            //execute something else asynchronously
        });     
    })(x);
}

Tuesday, June 5, 2012

Moq and IoC experiments

Hello all. It's been a while since I wrote something, why not restart with some interesting piece of code? I've embraced the whole TDD (Test Driven Development) movement and felt the need to use a mocking framework. What is does for you is basically mock the dependencies of the code you want to test, this way, you're not worried about your code accessing a service or a database, you just test your code and ignore the rest, as you're supposed to. Moq does this pretty well, imagine you have:
interface IMyClass
{
  int GetValue;
}

class MyClass : IMyClass
{
  int GetValue()
  {
    //goes to a service or database to come up with this value of 10
    return 10;
  }
}
To test your code, you don't need to execute the logic within GetValue, because your test subject is something else, so, you want to mock the behaviour of GetValue, so it returns a predefined value, and move on. You can do it with Moq, like this:
var myObject = new Mock<IMyClass>();
myObject.Setup(obj => obj.GetValue()).Returns(preDefinedValue);
This creates a new mocked instance of an object implementing your interface, IMyClass, and sets the return value of its method to what we need, so in order to use it, we just use the Object property of the mocked object, which gives us something of type IMyClass:
myObject.Object
Use case for this? imagine you have this code to get tested:
public bool ComputeSomething(IMyClass computerInstance)
{
  //do some calculations

  //you don't really care of what's coming from here,
  //you just want to test the code around it
  int returnValue = computerInstance.GetValue(); 
  //so some more calculations 
  return true|false;
}
This way, you could easily test this, right? Now, to go the extra mile with this, you could even use something like AutoFixture, that provides a plugin for Moq, so you can't use IoC to inject these mocked instances onto your test subjects classes, so easily as:
//Class1 looks like:
public class Class1
{
    private readonly IMyClass _obj;

    public Class1(IMyClass obj)
    {
        _obj = obj;
    }

    public int CalculateStuff()
    {
        int i = _obj.GetThatInt();

        return i * i;
    }
}


private IFixture _fixture;

[TestFixtureSetUp]
public void SetUp()
{
    //init autofixture
    _fixture = new Fixture().Customize(new AutoMoqCustomization());

    //setup our IMyClass dependencies, only once
    var myClassMocked = _fixture.Freeze<Mock<IMyClass>>();
    myClassMocked.Setup(x => x.GetValue()).Returns(10);

    //so here we have frozen a IMyClass instance on the fixture, so when we ask for something depending on it in the future from the fixture, it will auto inject this froze instance on it
}

[Test]
public void Test_that_method_from_CL()
{
    //ask autofixture for a Class1 instance with its dependencies mocked
    //and it provides, automatically, injecting the frozen IMyClass mock into Class1's contructor
    var cut = _fixture.CreateAnonymous<Class1>();

    //act & assert
    Assert.That(cut.CalculateStuff(), Is.EqualTo(100));
} 

Monday, October 4, 2010

Using MEF to extend applications

I'm back for another post, haven't posted for a long time now and hope to never do so again.

Getting to the point here, today I started using MEF, after months of tech talks, webcasts and tutorials, and I have to admit, it's really easy, clean and effective.

My scenario is this:

I have an application that needs to have a caching system, which will be implemented on a different project, and needs to abstract itself from the caching system being use.
So I coded an interface, obviously, to define what does the caching system need to implement.

public interface IPersist
  {
    void SaveToCache(string key, string payload, List< guid > contentIds);

    string GetFromCache(string key);

    void RefreshCache(string contentId);
  }

Then I created two example caching classes that implement this interface, which both reside on different visual studio projects:

[Export(typeof(IPersist))]
public class MemoryCache : IPersist
{

  public void SaveToCache(string key, string payload, List< guid > contentIds)
  {
    Console.WriteLine("memory cache " + key + " " + payload + " " + contentIds.Count.ToString());
  }

  public string GetFromCache(string key)
  {
    throw new NotImplementedException();
  }

  public void RefreshCache(string contentId)
  {
    throw new NotImplementedException();
  }
}

So, we have an interface named IPersist, we have two classes that implement this interface, and now we need to dinamically load one of these classes on our application, so we cannot add a reference to neither of them, because that way we would have to change our code each time we changed class, so how do we do it?

Our application code looks like this:

public partial class App : Application
  {
    private IPersist cacheSystem { get; set; }

    public App()
    {

      //something is missing here, how to load the assembly we want?

      cacheSystem.SaveToCache("key", "payload", new List< guid >());

      cacheSystem.GetFromCache("key");
    }
  }

What do we have to change to use MEF?
Lets assume the assembly file of the class that implements our cache system will be on the executing directory of our application (it could be elsewhere, or the class could be on the same assembly as our application even, but on this example it will be on the executing directory).
First we have to specify that our classes "export" themselves:

[Export(typeof(IPersist))]
public class MemoryCache : IPersist
{

  public void SaveToCache(string key, string payload, List< guid > contentIds)
  {
    Console.WriteLine("memory cache " + key + " " + payload + " " + contentIds.Count.ToString());
  }

  public string GetFromCache(string key)
  {
    throw new NotImplementedException();
  }

  public void RefreshCache(string contentId)
  {
    throw new NotImplementedException();
  }
}

[Export(typeof(IPersist))]
public class DiskCache : IPersist
{

  public void SaveToCache(string key, string payload, List< guid > contentIds)
  {
    Console.WriteLine("disk cache " + key + " " + payload + " " + contentIds.Count.ToString());
  }

  public string GetFromCache(string key)
  {
    throw new NotImplementedException();
  }

  public void RefreshCache(string contentId)
  {
    throw new NotImplementedException();
  }
}

So we added an Export attribute, specifying which type we are exporting, and this is important when things get more complicated, when you are exporting and importing lots of types.

Then on our application, we must create a catalog, on this case a DirectoryCatalog, since we are getting our exported classes on a directory, and then we create a CompositionContainer and pass our catalog as a parameter. The CompositionContainer is responsible for browsing the provided catalog and resolve connect the dots (match the exported classes to the imported ones on our application), and the code we need to do this is:

public partial class App : Application
  {
    [Import]
    private IPersist cacheSystem { get; set; }

    public App()
    {

      var catalog = new DirectoryCatalog(Environment.CurrentDirectory);
      var container = new CompositionContainer(catalog);
      container.ComposeParts(this);

      cacheSystem.SaveToCache("key", "payload", new List< guid >());

      cacheSystem.GetFromCache("key");
    }
  }

Which is, create a property that imports something of the type IPersist, create the catalog for the current directory, create the container which will resolve the export/import stuff, and order this resolution with the ComposeParts(this) method call, and finally compile one of our IPersist classes, put it on the executing dir and run our application.
Bam! Magically all is tied up and we can switch cache systems without compiling, just switch the dll file and you can change, just like that, our caching system implementation.

So, how powerful is this?

Please give feedback.

Thank you all, take care.

Thursday, May 27, 2010

Convert DataTable into POCO using attributes

Hello there.
A while ago, I had this issue, I have an older system which *still* works with the DataTable class, but still, I want to create my POCO (as we call it these days, the plain old CLR object) and work with it, LINQ it, etc, instead of the ugly DataTable object.
So I decided to do a method (that could be used as extension method on the DataTable class) that converted my DataTable to my POCO, on the fly.

The problem: mapping DataTable columns to POCO properties.
The solution: create a custom attribute class so I can define the correspondent column of the DataTable for each POCO property.

Here is the code:

C#

Usage
 var dt = new DataTable();
 dt.Columns.AddRange(
  new DataColumn[]
   {
    new DataColumn {ColumnName = "nome", DataType = typeof (string)},
    new DataColumn {ColumnName = "idade", DataType = typeof (int)}
   });
 dt.LoadDataRow(new object[] { "ricardo", 24 }, true);
 dt.LoadDataRow(new object[] { "manel", 45 }, true);

 List teste = ToObjectList(dt);

POCO
 public class Person
 {
  [ColumnMapping(FieldName = "nome")]
  public string Name
  {
   get;
   set;
  }

  [ColumnMapping(FieldName = "idade")]
  public int Age
  {
   get;
   set;
  }
 }

The magic
 public class ColumnMapping : Attribute
 {
  public string FieldName
  {
   get;
   set;
  }
 }

 private List ToObjectList(DataTable dtSource) where T : new()
 {
  var returnList = new List();

  for (var i = 0; i <= dtSource.Rows.Count - 1; i++)
  {
   var obj = new T();
   for (var j = 0; j <= dtSource.Columns.Count - 1; j++)
   {
    var col = (DataColumn) dtSource.Columns[j];     

    foreach (var pi in obj.GetType().GetProperties())
    {
     var fieldName = ((ColumnMapping)pi.GetCustomAttributes(typeof(ColumnMapping), false)[0]).FieldName;
     if (fieldName == col.ColumnName)
     {
      pi.SetValue(obj,dtSource.Rows[i][j],null);
      break;
     }
    }
   }
   returnList.Add(obj);
  }

  return returnList;
 }
VB.NET Usage
 Dim dt = New DataTable()
 dt.Columns.AddRange(New DataColumn() {New DataColumn(), New DataColumn()})
 dt.LoadDataRow(New Object() {"ricardo", 24}, True)
 dt.LoadDataRow(New Object() {"manel", 45}, True)

 Dim teste As List(Of Person) = ToObjectList(Of Person)(dt)
POCO
 Public Class Person
  Private _Name As String
      _
     Public Property Name() As String
         Get
             Return _Name
         End Get
         Set(ByVal value As String)
             _Name = value
         End Set
     End Property
     
  Private _Age As Integer
      _
     Public Property Age() As Integer
         Get
             Return _Age
         End Get
         Set(ByVal value As Integer)
             _Age = value
         End Set
     End Property
 End Class
The Magic
 Public Class ColumnMapping
  Inherits Attribute
  Private _FieldName As String
  Public Property FieldName() As String
   Get
    Return _FieldName
   End Get
   Set(ByVal value As String)
    _FieldName = value
   End Set
  End Property
 End Class

  Public Shared Function ToObjectList(Of T As New)(ByVal dtSource As DataTable) As List(Of T)
   Dim returnList = New List(Of T)()

   For i = 0 To dtSource.Rows.Count - 1
    Dim obj = New T()
    For j = 0 To dtSource.Columns.Count - 1
     Dim col = DirectCast(dtSource.Columns(j), DataColumn)

     For Each pi In obj.[GetType]().GetProperties()
      Dim fieldName = DirectCast(pi.GetCustomAttributes(GetType(ColumnMapping), False)(0), ColumnMapping).FieldName
      If fieldName = col.ColumnName Then
       pi.SetValue(obj, dtSource.Rows(i)(j), Nothing)
       Exit For
      End If
     Next
    Next
    returnList.Add(obj)
   Next

   Return returnList
  End Function

Thursday, April 22, 2010

C# Enum with char valued items

Hello again!
I'm finally back, and still I haven't fulfilled my promise of writing about .NET 4 and VS2010, but I'm working on it, and maybe I'll talk about VS2010 testing features as well and also Entity Framework 4 new hot stuff!

Focusing on the subject, what am I going to write about the Enum type?

- Can we assign an Enum item to anything that's not of the int type?
- Why would I even bother thinking about this?
- How can I handle converting something to Enum and back to something again?

First of all, YES, we can assign an Enum to something else, a char!
And how?
Just like you're thinking about it, yes:

public Enum myEnum {
value1 = 'a',
value2 = 'b'
}

And why would I think about this?
Have you ever had to write some DAL code or mapping and existing database to and ORM, say Entity Framework, and you had fields which contained, for some particular reason, a list of controlled chars, which aren't related to any other table, like a field called State which had the possible values, 'R' for Ready, 'P' for Pending and 'C' for cancelled, and you want to have some nice and type-safe way of manipulating this field on code and at the same time a generic way, which can be used everywhere, well, you can do it using those chars on an Enum type:

public Enum State {
Ready = 'R',
Pending = 'P',
Cancelled = 'C'
}

And how can I handle this? I'll sure try to do a State.ToString() and it will return me a number, why??
Because, actually, you can't have an Enum item with an associated char, but .NET lets you do this, and internally it converts your char to it's equivalent int representation (ASCII).
So, now you're thinking, so now what? How can I get my char??
Simple enough, just cast the Enum item to a char first, and then you get it's char representation:

string type = ((char)StateEnum).ToString();

This way you can extract the char from the int, and get your value!

This is for persisting your data to your datasource (convert the Enum item to the value that your datasource is expecting, the char).

But now you need to convert your char to the corresponding Enum item, when you get your char field from your datasource, right?
How can this be done?
Well I've coded a method to do that, with generics, lets see:

Code at Pastebin
public static T ToEnum< T >(string @string)
  {
   if (string.IsNullOrEmpty(@string))
   {
    throw new ArgumentException("Argument null or empty");
   }
   if (@string.Length > 1)
   {
    throw new ArgumentException("Argument length greater than one");
   }
   return (T)Enum.ToObject(typeof(T), @string[0]);
  }

So what you do here is accept a string (could be a char, it's just to make it simplier, since many ORMs map a char on the database to string, not chat), and then you check your parameters, ir they're not null, and if the length of the string is one (which matches a char), and then, you use the ToObject method from the Enum type, that accepts the return type you want to get, and the corresponding Enum item value (int or char) to convert to.

And that's it, you can use chars with an Enum object, isn't this awesome?
When i got around this, I just thought about the lots of times that I needed it...

Hope this helps you as much as it helped me.

Be back soon!

Tuesday, February 2, 2010

C# Word document manipulation without MSO Word installed!

Hi there folks!
I didn't forget about the promise I made, blogging about .NET 4.0 and VS 2010 new and spicy features, but before that, I need to blog about an interesting experience on developing a MSO word solution.

For starters, the discovery was when I found the Open XML SDK that allows me to manipulate my Word document without having office installed on the server running my application, which is a major breakthrough!
The code I used to add custom properties was taken from MSDN and I show it to you here:

public bool WDSetCustomProperty(string docName, string propertyName, object propertyValue, PropertyTypes propertyType)
    {
      const string documentRelationshipType =
        "http://schemas.openxmlformats.org/officeDocument/" +
        "2006/relationships/officeDocument";
      const string customPropertiesRelationshipType =
        "http://schemas.openxmlformats.org/officeDocument/" +
        "2006/relationships/custom-properties";
      const string customPropertiesSchema =
        "http://schemas.openxmlformats.org/officeDocument/" +
        "2006/custom-properties";
      const string customVTypesSchema =
        "http://schemas.openxmlformats.org/officeDocument/" +
        "2006/docPropsVTypes";

      bool retVal = false;
      PackagePart documentPart = null;
      string propertyTypeName = "vt:lpwstr";
      string propertyValueString = null;

      //  Calculate the correct type.
      switch (propertyType)
      {
        case PropertyTypes.DateTime:
          propertyTypeName = "vt:filetime";
          //  Make sure you were passed a real date, 
          //  and if so, format in the correct way. The date/time 
          //  value passed in should represent a UTC date/time.
          if (propertyValue.GetType() == typeof(System.DateTime))
          {
            propertyValueString = string.Format("{0:s}Z",
              Convert.ToDateTime(propertyValue));
          }
          break;

        case PropertyTypes.NumberInteger:
          propertyTypeName = "vt:i4";
          if (propertyValue.GetType() == typeof(System.Int32))
          {
            propertyValueString =
              Convert.ToInt32(propertyValue).ToString();
          }
          break;

        case PropertyTypes.NumberDouble:
          propertyTypeName = "vt:r8";
          if (propertyValue.GetType() == typeof(System.Double))
          {
            propertyValueString =
              Convert.ToDouble(propertyValue).ToString();
          }
          break;

        case PropertyTypes.Text:
          propertyTypeName = "vt:lpwstr";
          propertyValueString = Convert.ToString(propertyValue);
          break;

        case PropertyTypes.YesNo:
          propertyTypeName = "vt:bool";
          if (propertyValue.GetType() == typeof(System.Boolean))
          {
            //  Must be lower case!
            propertyValueString =
              Convert.ToBoolean(propertyValue).ToString().ToLower();
          }
          break;
      }

      if (propertyValueString == null)
      {
        //  If the code cannot convert the 
        //  property to a valid value, throw an exception.
        throw new InvalidDataException("Invalid parameter value.");
      }

      using (Package wdPackage = Package.Open(
        docName, FileMode.Open, FileAccess.ReadWrite))
      {
        //  Get the main document part (document.xml).
        foreach (PackageRelationship relationship in
          wdPackage.GetRelationshipsByType(documentRelationshipType))
        {
          Uri documentUri = PackUriHelper.ResolvePartUri(
            new Uri("/", UriKind.Relative), relationship.TargetUri);
          documentPart = wdPackage.GetPart(documentUri);
          //  There is only one document.
          break;
        }

        //  Work with the custom properties part.
        PackagePart customPropsPart = null;

        //  Get the custom part (custom.xml). It may not exist.
        foreach (PackageRelationship relationship in
          wdPackage.GetRelationshipsByType(
          customPropertiesRelationshipType))
        {
          Uri documentUri = PackUriHelper.ResolvePartUri(
            new Uri("/", UriKind.Relative), relationship.TargetUri);
          customPropsPart = wdPackage.GetPart(documentUri);
          //  There is only one custom properties part, 
          // if it exists at all.
          break;
        }

        //  Manage namespaces to perform Xml XPath queries.
        NameTable nt = new NameTable();
        XmlNamespaceManager nsManager = new XmlNamespaceManager(nt);
        nsManager.AddNamespace("d", customPropertiesSchema);
        nsManager.AddNamespace("vt", customVTypesSchema);

        Uri customPropsUri =
          new Uri("/docProps/custom.xml", UriKind.Relative);
        XmlDocument customPropsDoc = null;
        XmlNode rootNode = null;

        if (customPropsPart == null)
        {
          customPropsDoc = new XmlDocument(nt);

          //  The part does not exist. Create it now.
          customPropsPart = wdPackage.CreatePart(
            customPropsUri, "application/vnd.openxmlformats-officedocument.custom-properties+xml");

          //  Set up the rudimentary custom part.
          rootNode = customPropsDoc.
            CreateElement("Properties", customPropertiesSchema);
          rootNode.Attributes.Append(
            customPropsDoc.CreateAttribute("xmlns:vt"));
          rootNode.Attributes["xmlns:vt"].Value = customVTypesSchema;

          customPropsDoc.AppendChild(rootNode);

          //  Create the document's relationship to the 
          //  new custom properties part.
          wdPackage.CreateRelationship(customPropsUri,
            TargetMode.Internal, customPropertiesRelationshipType);
        }
        else
        {
          //  Load the contents of the custom properties part 
          //  into an XML document.
          customPropsDoc = new XmlDocument(nt);
          customPropsDoc.Load(customPropsPart.GetStream());
          rootNode = customPropsDoc.DocumentElement;
        }

        string searchString =
          string.Format("d:Properties/d:property[@name='{0}']",
          propertyName);
        XmlNode node = customPropsDoc.SelectSingleNode(
          searchString, nsManager);

        XmlNode valueNode = null;

        if (node != null)
        {
          //  You found the node. Now check its type.
          if (node.HasChildNodes)
          {
            valueNode = node.ChildNodes[0];
            if (valueNode != null)
            {
              string typeName = valueNode.Name;
              if (propertyTypeName == typeName)
              {
                //  The types are the same. 
                //  Replace the value of the node.
                valueNode.InnerText = propertyValueString;
                //  If the property existed, and its type
                //  has not changed, you are finished.
                retVal = true;
              }
              else
              {
                //  Types are different. Delete the node
                //  and clear the node variable.
                node.ParentNode.RemoveChild(node);
                node = null;
              }
            }
          }
        }

        if (node == null)
        {
          string pidValue = "2";

          XmlNode propertiesNode = customPropsDoc.DocumentElement;
          if (propertiesNode.HasChildNodes)
          {
            XmlNode lastNode = propertiesNode.LastChild;
            if (lastNode != null)
            {
              XmlAttribute pidAttr = lastNode.Attributes["pid"];
              if (!(pidAttr == null))
              {
                pidValue = pidAttr.Value;
                //  Increment pidValue, so that the new property
                //  gets a pid value one higher. This value should be 
                //  numeric, but it never hurt so to confirm.
                int value = 0;
                if (int.TryParse(pidValue, out value))
                {
                  pidValue = Convert.ToString(value + 1);
                }
              }
            }
          }

          node = customPropsDoc.
            CreateElement("property", customPropertiesSchema);
          node.Attributes.Append(customPropsDoc.CreateAttribute("name"));
          node.Attributes["name"].Value = propertyName;

          node.Attributes.Append(customPropsDoc.CreateAttribute("fmtid"));
          node.Attributes["fmtid"].Value =
            "{D5CDD505-2E9C-101B-9397-08002B2CF9AE}";

          node.Attributes.Append(customPropsDoc.CreateAttribute("pid"));
          node.Attributes["pid"].Value = pidValue;

          valueNode = customPropsDoc.
            CreateElement(propertyTypeName, customVTypesSchema);
          valueNode.InnerText = propertyValueString;
          node.AppendChild(valueNode);
          rootNode.AppendChild(node);
          retVal = true;

        }

        //  Save the properties XML back to its part.
        customPropsDoc.Save(customPropsPart.
          GetStream(FileMode.Create, FileAccess.Write));

      }



      return retVal;
    }

The purpose of having this is to write some custom properties, for my Word Add-in to work properly, which is quite handy in most situations.

Hope this is as much value to you as it was to me!

Be back soon

Friday, January 15, 2010

JCrop + Thickbox iframe + Internet Explorer 8 (Nasty IE bug fix)

Hello guys.
Before posting about .NET Framework 4.0, I have to tell you about an episode (another one) about the horrifying experience that is programming IE compatible javascript.
The scenario:

I have a web form with a input file, that I need to crop & resize the image (if it is one), on a thickbox iframe.

So I create submit my form to an iframe, and when the iframe is loaded, I run the JCrop plugin.
So far so good..on Firefox..
Then I test this on IE8, nothing, the image doesn't appear or the image appears, but no JCrop functionality whatsoever, and why? Because IE8 (an 7 as far as I know) doesn't load the image in a timely fashion, or when it's supposed to be loaded! Nothing works! window load event, image load event, document ready, document load, nothing!

The Trick: having the jcrop call inside a setTimeout, with 1 ms only...

setTimeout("$('imgEdit').JCrop();",1); //<- and voilá! it's working!

It's a shame on 2010 we still need to hack to get things working on IE.

Hope this save you a good couple of yours, like it would if I had it.