Tuesday, 24 July 2012

Embedding file as resource in dll

* In Visual Studio file properties set Build Action as Embedded Resource

And then you can read a file using this code

private static string ReadResourceFile(string defaultNamespace, string fileName)
{
  var resource = string.Format("{0}.{1}", defaultNamespace, fileName);
  using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resource))
  {
    using (var sr = new StreamReader(stream))
    {
      return sr.ReadToEnd();
    }
  }
}

Parse XML to object model in C# using XSD utility

* Run xsd Visual Studio command line utility to generate object from xsd file (from Visual Studio Command Prompt)

xsd-util
* Then add the cs file to your project (same place as your xsd file)
xsd-contacts
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    targetNamespace="urn:contacts"
    xmlns:bks="urn:contacts">
 
  <xsd:element name="contacts" type="bks:Contacts"/>
 
  <xsd:complexType name="Contacts">
    <xsd:sequence>
      <xsd:element name="contact"
        type="bks:Contact"
        minOccurs="0"
        maxOccurs="unbounded"/>
  </xsd:sequence>
  </xsd:complexType>
 
  <xsd:complexType name="Contact">
  <xsd:sequence>
    <xsd:element name="firstName" type="xsd:string"/>
    <xsd:element name="lastName"  type="xsd:string"/>    
    <xsd:element name="age"     type="xsd:int" />
    <xsd:element name="dob"     type="xsd:date" />
    <xsd:element name="salary"  type="xsd:float" />
  </xsd:sequence>
  <xsd:attribute name="id"   type="xsd:int"/>
  </xsd:complexType>
</xsd:schema>
<?xml version="1.0" encoding="utf-8" ?>
<contacts>
  <contact id='1'>
    <firstName>Michael</firstName>
    <lastName>Jordan</lastName>
    <age>40</age>
    <dob>1965</dob>
    <salary>100.35</salary>
  </contact>
  <contact id='2'>
    <firstName>Scottie</firstName>
    <lastName>Pippen</lastName>
    <age>38</age>
    <dob>1967</dob>
    <salary>55.28</salary>
  </contact>
</contacts>
[Test]
public void Test()
{
  Contacts contacts = null;
 
  var xRoot = new XmlRootAttribute();
  xRoot.ElementName = "contacts";
  //xRoot.Namespace = "http://<if you need one>";
  xRoot.IsNullable = true;
 
  var serializer = new XmlSerializer(typeof(Contacts), xRoot);
 
  using (TextReader reader = new StreamReader(@"contacts.xml"))
  {
    contacts = (Contacts)serializer.Deserialize(reader);
  }
 
  Console.WriteLine(contacts.contact.Count());
  Console.WriteLine(contacts.contact[0].firstName);
  Console.WriteLine(contacts.contact[0].id);
}

Parse XML to dynamic object in C#

<?xml version="1.0" encoding="utf-8" ?>
<contacts>
  <contact id='1'>
    <firstName>Michael</firstName>
    <lastName>Jordan</lastName>
    <age>40</age>
    <dob>1965</dob>
    <salary>100.35</salary>
  </contact>
  <contact id='2'>
    <firstName>Scottie</firstName>
    <lastName>Pippen</lastName>
    <age>38</age>
    <dob>1967</dob>
    <salary>55.28</salary>
  </contact>
</contacts>
public class XmlToDynamic
{
  public static void Parse(dynamic parent, XElement node)
  {
    if (node.HasElements)
    {
      if (node.Elements(node.Elements().First().Name.LocalName).Count() > 1)
      {
        //list
        var item = new ExpandoObject();
        var list = new List<dynamic>();
        foreach (var element in node.Elements())
        {            
          Parse(list, element);            
        }
 
        AddProperty(item, node.Elements().First().Name.LocalName, list);
        AddProperty(parent, node.Name.ToString(), item);
      }
      else
      {
        var item = new ExpandoObject();
 
        foreach (var attribute in node.Attributes())
        {
          AddProperty(item, attribute.Name.ToString(), attribute.Value.Trim());
        }
 
        //element
        foreach (var element in node.Elements())
        {
          Parse(item, element);
        }
 
        AddProperty(parent, node.Name.ToString(), item);
      }
    }
    else
    {
      AddProperty(parent, node.Name.ToString(), node.Value.Trim());
    }
  }
 
  private static void AddProperty(dynamic parent, string name, object value)
  {
    if (parent is List<dynamic>)
    {
      (parent as List<dynamic>).Add(value);
    }
    else
    {
      (parent as IDictionary<String, object>)[name] = value;
    }
  }
}
[Test]
public void Test()
{
  //read from text
  //var xDoc = XDocument.Parse(txt);
 
  //read from url
  //var request = WebRequest.Create(@"http://...") as HttpWebRequest;
  //request.Credentials = CredentialCache.DefaultNetworkCredentials;
  //var xDoc = XDocument.Load(request.GetResponse().GetResponseStream());
 
  //read from file
  var xDoc = XDocument.Load(new StreamReader("contacts.xml"));
 
  dynamic root = new ExpandoObject();
 
  XmlToDynamic.Parse(root, xDoc.Elements().First());
 
  Console.WriteLine(root.contacts.contact.Count);
  Console.WriteLine(root.contacts.contact[0].firstName);
  Console.WriteLine(root.contacts.contact[0].id);
}

Monday, 16 July 2012

C# Scripting with Microsoft Roslyn

If you’re not familiar with Microsoft “Roslyn” please read Interactive C# Microsoft Roslyn.

[TestFixture]
public class TestScript
{
  [Test]
  public void TestSimple()
  {
    var engine = new ScriptEngine();
    Console.WriteLine(engine.Execute("1+1"));
    Console.WriteLine(engine.Execute<int>("1+1"));
  }
 
  [Test]
  public void TestSession()
  {
    var engine = new ScriptEngine();
    var session = Session.Create();
      
    engine.Execute("int x = 1, y;", session);
    engine.Execute("if(x==1)y = 10; else y = 20;",session);
    Console.WriteLine(engine.Execute("y", session));
  }
 
  [Test]
  public void TestScriptFile()
  {
    var engine = new ScriptEngine();
    ScriptContext context = new ScriptContext();
    engine.ExecuteFile("Test.csx", context);
  }
 
  [Test]
  public void TestScriptFileHostObject()
  {
    var context = new ScriptContext();
    var engine = new ScriptEngine(new[] { context.GetType().Assembly.Location });
    var session = Session.Create(context);
 
    context.Name = "Tom";
    context.Parameters.Add("Input", "Hello");
    engine.ExecuteFile("TestHost.csx", session);
 
    Console.WriteLine(context.Parameters["Output"]);
  }
}
 
public class ScriptContext
{
  public Dictionary<string, object> Parameters { get; set; }
  public string Name { get; set; }
 
  public ScriptContext()
  {
    Parameters = new Dictionary<string, object>();
  }
}

Test.csx

using System;
 
var hello = "Hello";
Console.WriteLine(hello);

TestHost.csx

using System;
 
var output = string.Format("{0} {1}",Parameters["Input"], Name);
 
Parameters.Add("Output", output);

You can read more on the subject here Introduction to the Roslyn Scripting API

Friday, 13 July 2012

Log4Net Console in color

<?xml version="1.0"?>
<configuration>
  <configSections>
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"/>
  </configSections>
  <log4net>
    <appender name="Console" type="log4net.Appender.ColoredConsoleAppender">
      <mapping>
        <level value="ERROR"/>
        <foreColor value="Red, HighIntensity"/>
      </mapping>
      <mapping>
        <level value="WARN"/>
        <backColor value="Yellow"/>
        <foreColor value="Blue, HighIntensity"/>
      </mapping>
      <mapping>
        <level value="INFO"/>
        <foreColor value="White"/>
      </mapping>
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%d{HH:mm:ss} %-5p %M: %m%n" />
      </layout>
      <param name="Threshold" value="INFO" />
    </appender>
    <root>
      <appender-ref ref="Console" />
    </root>
  </log4net>
</configuration>
log4netcolor

More info about ColoredConsoleAppender

Interactive C# Microsoft Roslyn

Microsoft Roslyn CTP adds Interactive C# window to Visual Studio 2010/2012 and adds support for scripting and interactive use of C#

roslyn1

It also allows you to write script files *.csx

roslyn2

The easiest way to initialize C# Interactive window is to right click on any C# project and choose 'Reset Interactive from Project' from context menu

roslyn3

Then you can execute any C# code from your project

public class Sample
{
    public List<string> Run()
    {
        return new List<string>(){"One","Two","Three","Four"};
    }
}

roslyn4

To execute script use #load command

roslyn5

Other useful commands

#r ".\myproject.exe"  //loads executable or dll
#load ".\setup.csx"   //loads script

And this is good introduction to Microsoft “Roslyn”

Thursday, 12 July 2012

C# Crop white space from around the image

This code will crop the image based on all white and transparent pixels from around the image

cropwhitespacecropwhitespace2

public static Bitmap CropWhiteSpace(Bitmap bmp)
{
  int w = bmp.Width;
  int h = bmp.Height;
  int white = 0xffffff;
 
  Func<int, bool> allWhiteRow = r =>
  {
    for (int i = 0; i < w; ++i)
      if ((bmp.GetPixel(i, r).ToArgb() & white) != white)
        return false;
    return true;
  };
 
  Func<int, bool> allWhiteColumn = c =>
  {
    for (int i = 0; i < h; ++i)
      if ((bmp.GetPixel(c, i).ToArgb() & white) != white)
        return false;
    return true;
  };
 
  int topmost = 0;
  for (int row = 0; row < h; ++row)
  {
    if (!allWhiteRow(row))
      break;
    topmost = row;
  }
 
  int bottommost = 0;
  for (int row = h - 1; row >= 0; --row)
  {
    if (!allWhiteRow(row))
      break;
    bottommost = row;
  }
 
  int leftmost = 0, rightmost = 0;
  for (int col = 0; col < w; ++col)
  {
    if (!allWhiteColumn(col))
      break;
    leftmost = col;
  }
 
  for (int col = w - 1; col >= 0; --col)
  {
    if (!allWhiteColumn(col))
      break;
    rightmost = col;
  }
 
  if (rightmost == 0) rightmost = w; // As reached left
  if (bottommost == 0) bottommost = h; // As reached top.
 
  int croppedWidth = rightmost - leftmost;
  int croppedHeight = bottommost - topmost;
 
  if (croppedWidth == 0) // No border on left or right
  {
    leftmost = 0;
    croppedWidth = w;
  }
 
  if (croppedHeight == 0) // No border on top or bottom
  {
    topmost = 0;
    croppedHeight = h;
  }
 
  try
  {
    var target = new Bitmap(croppedWidth, croppedHeight);
    using (Graphics g = Graphics.FromImage(target))
    {
      g.DrawImage(bmp,
        new RectangleF(0, 0, croppedWidth, croppedHeight),
        new RectangleF(leftmost, topmost, croppedWidth, croppedHeight),
        GraphicsUnit.Pixel);
    }
    return target;
  }
  catch (Exception ex)
  {
    throw new Exception(
      string.Format("Values are topmost={0} btm={1} left={2} right={3} croppedWidth={4} croppedHeight={5}", topmost, bottommost, leftmost, rightmost, croppedWidth, croppedHeight),
      ex);
  }
}
[Test]
public void Test()
{
  var inputPath = "image.png";
  var outputPath = inputPath.Replace(".png", "-out.png");
 
  var bitmap = new Bitmap(inputPath);
  var cropped = CropWhiteSpace(bitmap);
  cropped.Save(outputPath, ImageFormat.Png); 
}

C# LINQ GroupBy example

public void TestGroupBy()
{
  var people = new[]
  {
    new { Name="John", City="London", Side="South", Age=20},
    new { Name="John", City="London", Side="North", Age=55},
    new { Name="Eli", City="London", Side="North", Age=39},
    new { Name="Anna", City="NY", Side="North", Age=23},
    new { Name="Marc", City="NY", Side="South", Age=51},
    new { Name="Julie", City="NY", Side="South", Age=67},
  }.ToList();
 
  var ageByCitySide = people
      .GroupBy(p => new {p.City, p.Side})
      .Select(r => new {r.Key.City, r.Key.Side, AverageAge = r.Average(p => p.Age)})
      .OrderBy(p=>p.AverageAge);
 
  foreach (var p in ageByCitySide)
  {
    Console.WriteLine("{0},{1} AvgAge:{2}",p.City,p.Side,p.AverageAge);
  }
 
  var youngOldByCitySide = people
      .GroupBy(p => new { p.City, p.Side }, r => new { r.Age, YoungOld = (r.Age > 50 ? "old" : "young")})
      .Select(r => new { r.Key.City, r.Key.Side, NoOfYoung=r.Count(p=>p.YoungOld =="young"), NoOfOld=r.Count(p=>p.YoungOld =="old"), AverageAge = r.Average(p => p.Age) })
      .OrderBy(p => p.AverageAge);
 
  foreach (var p in youngOldByCitySide)
  {
    Console.WriteLine("{0},{1} AvgAge:{2}, YoungPpl:{3}, OldPpl:{4}", p.City, p.Side, p.AverageAge, p.NoOfYoung, p.NoOfOld);
  }
}