Saturday, November 16, 2013

Unity container and Factory pattern

Recently I had merged Unity container and Factory pattern to create objects in a central place. Below is the code for the same. Thought it would be useful to you guys!!

using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.Configuration;

public class DependencyFactory
    {
        public static T GetObject()
        {
            IUnityContainer container = new UnityContainer();
            UnityConfigurationSection section =
              (UnityConfigurationSection)ConfigurationManager.GetSection(ConfigurationManager.AppSettings["UnityContainer"]);
            section.Configure(container);
            T res = container.Resolve();
            return res;
        }

        public static T GetObject(params ResolverOverride[] overrides)
        {
            IUnityContainer container = new UnityContainer();
            UnityConfigurationSection section =
              (UnityConfigurationSection)ConfigurationManager.GetSection(ConfigurationManager.AppSettings["UnityContainer"]);
            section.Configure(container);
            T res = container.Resolve(overrides);
            return res;
        }
    }


  <configuration>
   <configSections>
    <section name="TEST_UNITY"
       type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, 
               Microsoft.Practices.Unity.Configuration" />
  </configSections>
  <TEST_UNITY>
    <containers>
      <container>
        <types>
          <type
             type="Unity.Sample.Repositories.IEnrollmentRepository,Unity.Sample"
             mapTo="Unity.Sample.Repositories.DummyEnrollmentRepository,
                      Unity.Sample" />
          <type
             type="Unity.Sample.Repositories.ICustomerDetailsRepository,Unity.Sample"
             mapTo="Unity.Sample.Repositories.DummyCustomerDetailsRepository,
                      Unity.Sample" />
          <type
             type="Unity.Sample.Repositories.ICustomerRepository,Unity.Sample"
             mapTo="Unity.Sample.Repositories.DummyCustomerRepository,
                      Unity.Sample" />
           <type
             type="Unity.Sample.Repositories.IBIBRepository,Unity.Sample"
             mapTo="Unity.Sample.Repositories.DummyBIBRepository,
                      Unity.Sample" />
          <type
             type="Unity.Sample.Repositories.ILockBoxRepository,Unity.Sample"
             mapTo="Unity.Sample.Repositories.DummyLockBoxRepository,
                      Unity.Sample" />
          <type
             type="Unity.Sample.Interfaces.IBIB,Unity.Sample"
             mapTo="Unity.Sample.Impl.DummyBIB,
                      Unity.Sample" />
          <type
               type="Unity.Sample.Interfaces.ILockBox,Unity.Sample"
               mapTo="Unity.Sample.Impl.DummyLockBox,
                      Unity.Sample" />
        </types>
      </container>
    </containers>
  </TEST_UNITY>
  <appSettings>
    <add key="UnityContainer" value="TEST_UNITY"/>
  </appSettings>
</configuration>
   
 

My experiments with TPL Dataflow

Another WOW technique from the house of Microsoft is the TPL Dataflow for dealing with collections in parallel utilizing the multiple CPU's available. I was doing some experiments with it recently and the code is below;

I implemented the below process using TPL;


class Program
    {
        static Employer employer = new Employer();
        static EmployeeCollection employees = new EmployeeCollection();
        static int i = 0;

        static void Main(string[] args)
        {
            LoadEmployees();
            PayEmployees();
        }

        static void LoadEmployees()
        {
            string fileName = @"C:\Users\m1003014\Desktop\employees.txt";
            var inputBlock = new BufferBlock();
            var processBlock = new TransformBlock(
                x =>
                {
                    Employee emp = null;
                    string[] values = x.Split(@";".ToCharArray());
                    BankAccount bankAccount = new BankAccount(Convert.ToDecimal(values[6]));
                    emp = new Employee(i++, values[0], values[1], Convert.ToDecimal(values[2]), bankAccount);
                    if (Convert.ToDecimal(values[3]) > 0)
                    {
                        emp.TakeAdvance(Convert.ToDecimal(values[3]), Convert.ToDecimal(values[4]), Convert.ToDecimal(values[5]));
                    }
                    return emp;
                });
            var outputBlock = new ActionBlock(
                x =>
                {
                    employees.Add(x);
                });

            using (inputBlock.LinkTo(processBlock))
            using (processBlock.LinkTo(outputBlock))
            {
                inputBlock.Completion.ContinueWith(t => processBlock.Complete());
                processBlock.Completion.ContinueWith(t => outputBlock.Complete());

                if (File.Exists(fileName))
                {
                    StreamReader sr = new StreamReader(fileName);
                    sr.ReadLine();
                    String line = sr.ReadLine();

                    do
                    {
                        inputBlock.Post(line);
                        line = sr.ReadLine();
                    } while (line != null);
                }
                inputBlock.Complete();
                outputBlock.Completion.Wait();
            }
        }

        static void PayEmployees()
        {
            var inputBlock = new BufferBlock();
            var processBlock = new TransformBlock(
                x =>
                {
                    employer.PaySalary(x);
                    return x;
                });
            var outputBlock = new ActionBlock(
                x =>
                {
                    Console.WriteLine(string.Format("The salary of '{1}' INR has been paid to '{0}'", x.FirstName, x.SalaryTobePaid));
                });
            using (inputBlock.LinkTo(processBlock))
            using (processBlock.LinkTo(outputBlock))
            {
                inputBlock.Completion.ContinueWith(t => processBlock.Complete());
                processBlock.Completion.ContinueWith(t => outputBlock.Complete());

                foreach (Employee emp in employees)
                {
                    inputBlock.Post(emp);
                }

                inputBlock.Complete();
                outputBlock.Completion.Wait();
            }
        }
    }

 public class Employee
    {
        int _id;
        string _firstName;
        string _lastName;
        decimal _salary;
        decimal _advanceTaken;
        decimal _monthlyDeduction;
        decimal _tenure;
        decimal _pendingTenure;
        decimal _advanceLeft;
        BankAccount _employeeBankAccount;

        public Employee(int id, string firstName, string lastName, decimal salary, BankAccount employeeBankAccount)
        {
            _id = id;
            _firstName = firstName;
            _lastName = lastName;
            _salary = salary;
            _employeeBankAccount = employeeBankAccount;
        }

        public int EmployeeID
        {
            get { return _id; }
        }

        public string FirstName
        {
            get { return _firstName; }
        }

        public string LastName
        {
            get { return _firstName; }
        }

        public decimal Salary
        {
            get { return _salary; }
        }

        public decimal AdvanceTaken
        {
            get { return _advanceTaken; }
        }

        public decimal AdvanceLeft
        {
            get { return _advanceLeft; }
        }
        public decimal SalaryTobePaid
        {
            get { return _salary - _monthlyDeduction; }
        }

        public BankAccount EmployeeBankAccount
        {
            get { return _employeeBankAccount; }
        }

        public void TakeAdvance(decimal amount, decimal monthlyDeduction, decimal tenure)
        {
            _advanceTaken = amount;
            _advanceLeft = amount;
            _monthlyDeduction = monthlyDeduction;
            _tenure = tenure;
            _pendingTenure = tenure;
        }

        public void UpdateAdvance()
        {
            _advanceLeft -= _monthlyDeduction;
            _pendingTenure -= 1;
        }

        public void CreditSalary()
        {
            _employeeBankAccount.Credit(SalaryTobePaid);
        }

        public bool HasTakenAdvance()
        {
            if (_pendingTenure > 0)
                return true;
            else
                return false;
        }
    }

    public class BankAccount
    {
        decimal _balance;

        public BankAccount(decimal balance)
        {
            _balance = balance;
        }

        public decimal Balance
        {
            get { return _balance; }
        }

        public void Credit(decimal amount)
        {
            _balance += amount;
        }

        public void Debit(decimal amount)
        {
            if (_balance - amount < 0)
                throw new Exception("Insufficient fund available");
            _balance -= amount;
        }
    }

    public class EmployeeCollection : KeyedCollection
    {
        public EmployeeCollection()
            : base()
        {
        }

        protected override int GetKeyForItem(Employee emp)
        {
            return emp.EmployeeID;
        }
    }

    public class MonthlySummary
    {
        int _totalEmployeesReceivingSalary;
        decimal _totalMonthlySalary;
        decimal _totalMonthlyRecovery;

        public int TotalEmployeesReceivingSalary
        {
            get { return _totalEmployeesReceivingSalary; }
        }

        public decimal TotalMonthlySalary
        {
            get { return _totalMonthlySalary; }
        }

        public decimal TotalMonthlyRecovery
        {
            get { return _totalMonthlyRecovery; }
        }

        public void UpdateThisEmployeeDetails(Employee emp)
        {
            _totalEmployeesReceivingSalary += 1;
            _totalMonthlySalary += emp.SalaryTobePaid;
            _totalMonthlyRecovery += emp.SalaryTobePaid - emp.Salary;
        }
    }

    public class Employer
    {
        BankAccount _employerBankAccount;
        MonthlySummary _monthlySummary;

        public Employer()
        {
            _employerBankAccount = new BankAccount(100000000);
            _monthlySummary = new MonthlySummary();
        }

        public void PaySalary(Employee emp)
        {
            _employerBankAccount.Debit(emp.SalaryTobePaid);
            emp.CreditSalary();
            _monthlySummary.UpdateThisEmployeeDetails(emp);
        }
    }

Sample input file;
FirstName;LastName;Salary;AdvanceTaken;MonthlyDeduction;Tenure;AccountBalance
Raja;vel;10000;0;0;0;200000
Bal;ji;10000;0;0;0;100000
test;test;10000;100000;5000;20;10000

TDD using Moq

Recently I was experimenting TDD in C# using Moq mocking framework. An awesome mocking framework. Some samples are below;

For more details on Moq refer this link;
https://code.google.com/p/moq/

[TestMethod]
        public void TestEnrollCustomer()
        {
            var enrollment = new Mock(MockBehavior.Strict, MockCustomerDetails.One);
            bool actual = false;
              actual=  enrollment.Object.EnrollCustomer();
            Assert.AreEqual(true, actual, "Failed to execute");
        }

public class MockCustomerDetails
    {
        static CustomerDetails customer1 = null;
        static CustomerDetails customer2 = null;
        static CustomerDetails customer3 = null;
        static MockCustomerDetails()
        {
            customer1 = new CustomerDetails(MockCustomer.One, MockBIB.One, MockLockBox.One);
            customer2 = new CustomerDetails(MockCustomer.Two, MockBIB.Two, MockLockBox.Two);
            customer3 = new CustomerDetails(MockCustomer.Three, MockBIB.Three, MockLockBox.Three);
        }

        public static CustomerDetails One
        {
            get
            {
                return customer1;
            }
        }
        public static CustomerDetails Two
        {
            get
            {
                return customer2;
            }
        }
        public static CustomerDetails Three
        {
            get
            {
                return customer3;
            }
        }
    }

public class MockBIB
    {
        static DummyBIB bib1 = null;
        static DummyBIB bib2 = null;
        static DummyBIB bib3 = null;

        static MockBIB()
        {
            bib1 = new DummyBIB("1213121");
            bib2 = new DummyBIB("12131zcxc21");
            bib3 = new DummyBIB("12wewe13121");
        }
        public static DummyBIB One
        {
            get
            {
                return bib1;
            }
        }
        public static DummyBIB Two
        {
            get
            {
                return bib2;
            }
        }
        public static DummyBIB Three
        {
            get
            {
                return bib3;
            }
        }
    }

public class MockLockBox
    {
        static DummyLockBox lock1 = null;
        static DummyLockBox lock2 = null;
        static DummyLockBox lock3 = null;

        static MockLockBox()
        {
            lock1 = new DummyLockBox("1213121");
            lock2 = new DummyLockBox("121sdsad3121"); 
            lock3 = new DummyLockBox("1213wrtwrtrw121");
        }
        public static DummyLockBox One
        {
            get
            {
                return lock1;
            }
        }
        public static DummyLockBox Two
        {
            get
            {
                return lock2;
            }
        }
        public static DummyLockBox Three
        {
            get
            {
                return lock3;
            }
        }
    }

Monday, February 20, 2012

Dynamic XPATH in XSLT using C#

Recently I had a task of converting a flat XML to hierarchical XML deserializable to .NET entities. Everything was smooth until I got into a situation where-in I had some elements like shown below


...
<CCY1>GBP</CCY1>
<Value1>1.34</Value1>
<CCY2>EUR</CCY2>


<Value2>1.34</Value2>
...


which needed to be like after conversion as shown below


....
<CCYDetails>
<CCYDetail>
<CCY>GBP</CCY>
<Value>1.34</Value>
....
</CCYDetails>
</CCYDetail>
...
 
After some research in internet, I figured out that it is not straight forward in XSLT. It needs some help of scripting language. Since I am from .NET background, I wasn't able to find much help in this regard. Then I found one code in one of the forum threads and tweaked a bit to get it working.


XSLT
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
xmlns:user="http://tempuri.org/user">
<msxsl:script language="CSharp" implements-prefix="user">
<![CDATA[
public XPathNodeIterator FilterNodes(XPathNodeIterator context,string xpath)
{
context.MoveNext();
return context.Current.Select(xpath);
}
]]>
</msxsl:script>
<xsl:template match="/">
<root>
<CCYDetailss>
<xsl:for-each select="MinPayInAmendment">
<xsl:call-template name="ccy_loop">
</xsl:call-template>
</xsl:for-each>
</CCYDetails>
</root>
</xsl:template>
<xsl:template name="ccy_loop">
<xsl:param name="num">1</xsl:param>
<xsl:if test="not ($num=17)">
<xsl:variable name="ccy" select="concat('CCY',$num)">
</xsl:variable>
<xsl:variable name="new" select="concat('New',$num)">
</xsl:variable>
<CCYDetail>
<CCY>
<xsl:value-of select="user:FilterNodes(.,$ccy)"/>
</CCY>
<New>
<xsl:value-of select="user:FilterNodes(.,$new)"/>
</New>
</CCYDetail>
<xsl:call-template name="ccy_loop">
<xsl:with-param name="num">
<xsl:value-of select="$num+1"></xsl:value-of>
</xsl:with-param>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>


C#
XPathDocument xpath = new XPathDocument(@"C:\input_xml.xml");

XPathNavigator navi = xpath.CreateNavigator();
XsltSettings settings = new XsltSettings();
settings.EnableScript = true;
settings.EnableDocumentFunction = true;
XslCompiledTransform transform = new XslCompiledTransform();
transform.Load(@"C:\XSLTFile1.xslt",settings,new XmlUrlResolver());
MemoryStream resultStream = new MemoryStream();
XmlWriterSettings writer_settings = new XmlWriterSettings();
writer_settings.Indent = true;
XmlWriter writer = XmlWriter.Create(resultStream,writer_settings);
transform.Transform(xpath, null, writer);
resultStream.Position = 0;
StreamReader stream = new StreamReader(resultStream);
Console.WriteLine(stream.ReadToEnd());
writer.Close();



PDF to XML using iTextsharp

Here is the very simple way of creating the XML from PDF document. I used Form fields in the PDF document. Then using the iTextsharp, I looped through the Acrofields or Form fields and created the flat XML document out of it. You can customize to create more complex structures if need be.

XmlDocument doc = new XmlDocument();
PdfReader reader = new PdfReader(@"C:\Input.pdf");
AcroFields fields = reader.AcroFields;
doc.LoadXml(string.Format("<{0}/>", root));
foreach (string keyName in fields.Fields.Keys)
{
AcroFields.Item item = fields.GetFieldItem(keyName);
XmlElement elt = doc.CreateElement(keyName);
elt.InnerXml = "<![CDATA[" + fields.GetField(keyName) + "]]>"";
doc.DocumentElement.AppendChild(elt);
}

doc.Save(@"C:\output.xml");