Sony Arouje

a programmer's log

Archive for the ‘.NET’ Category

Diagnostic Trace (SVCLog) configuration for WCF

leave a comment »

Whenever I write any WCF service, I need to search in my snippets to find out the configuration to add Diagnostic traces for WCF. This post help me to pick the configuration any time when ever I need it.

  <system.diagnostics>
    <sources>
      <source name="System.ServiceModel"
              switchValue="Information, ActivityTracing"
              propagateActivity="true">
        <listeners>
          <add name="traceListener"
              type="System.Diagnostics.XmlWriterTraceListener"
              initializeData= "F:\Sony\Traces.svclog" />
        </listeners>
      </source>
    </sources>
  </system.diagnostics>

 

Adding this configuration allows the WCF to log all the communication between the client and host in xml format. You can view svclog using SvcTraceViewer.exe, it shipped with Visual Studio and can found out in WCF installation location (C:\Program Files\Microsoft SDKs\Windows\v7.0A\bin)

Written by Sony Arouje

November 10, 2011 at 2:34 pm

Posted in .NET, WCF

Tagged with , ,

Read app.config setting during installation

with 2 comments

I am working on a windows service and some specific reason the service name is stored in app.config file. One of the issue I have to solve while creating the installer is reading the service name from app.config of the service. I thought I can read it using ConfigurationManager (default approach). But it will not work out, ConfigurationManager will always return the serviceName as null, even though app.config has value. The reason behind this is the exe running my Installer is InstallUtil.exe and ConfigurationManager will look for InstallUtil.exe.config, so end up getting wrong result.

Google search shows that I have to load the config explicitly and then read the settings. To load the config file we need to specify the file path, I used reflection to get the path. The code is below

Assembly executingAssembly = Assembly.GetAssembly(typeof(WinServiceInstaller));
string targetDir = executingAssembly.Location;

Configuration config = ConfigurationManager.OpenExeConfiguration(targetDir);
string serviceName = config.AppSettings.Settings["ServiceName"].Value.ToString();

 

I called the above code in the constructor of WinServiceInstaller class. Now I am able to access the serviceName from the installer class.

 

 

 

Written by Sony Arouje

November 4, 2011 at 7:06 pm

Posted in .NET, Misc

Tagged with , ,

A Microsoft KB Article–Example of How not to write code

leave a comment »

Couple of weeks back I was doing some parsing of xml string and want to replace the special characters in the data. I didn’t remember the list of special characters, like others I fire up a search in Google. One of the google search result leads to a Microsoft KB article. I got what I wanted, list of special character I have to deal with. The article also provided a special character replacement logic, to my surprise the code was very lengthy and looks odd to me.

I decided to scan the code in little more detail. Below is the code from the article.

Dim filepath As String = "C:\customers.xml"
Private Sub ReplaceSpecialChars(ByVal linenumber As Long)
        Dim strm As StreamReader
        Dim strline As String
        Dim strreplace As String

        Dim tempfile As String = "C:\temp.xml"
        Try
            FileCopy(filepath, tempfile)
        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try

        Dim strmwriter As New StreamWriter(filepath)
        strmwriter.AutoFlush = True

        strm = New StreamReader(tempfile)


        Dim i As Long = 0
        While i < linenumber - 1
            strline = strm.ReadLine
            strmwriter.WriteLine(strline)
            i = i + 1
        End While

        strline = strm.ReadLine
        Dim lineposition As Int32
        lineposition = InStr(strline, "&")
        If lineposition > 0 Then
            strreplace = "&amp;"
        Else
            lineposition = InStr(2, strline, "<")
            If lineposition > 0 Then
                strreplace = "<"
            End If
        End If
        strline = Mid(strline, 1, lineposition - 1) + strreplace + Mid(strline, lineposition + 1)
        strmwriter.WriteLine(strline)

        strline = strm.ReadToEnd
        strmwriter.WriteLine(strline)

        strm.Close()
        strm = Nothing

        strmwriter.Flush()
        strmwriter.Close()
        strmwriter = Nothing

    End Sub

    Public Function LoadXMLDoc() As XmlDocument
        Dim xdoc As XmlDocument
        Dim lnum As Long
        Dim pos As Long
        Dim Newxml As String
        Try
            xdoc = New XmlDocument()
            xdoc.Load(filepath)
        Catch ex As XmlException
            MessageBox.Show(ex.Message)
            lnum = ex.LineNumber
            ReplaceSpecialChars(lnum)

            xdoc = LoadXMLDoc()

        End Try
        Return (xdoc)
    End Function
 

The user calls the LoadXMLDoc() function, the function loads the xml file located in the disk. The weird thing is, the function does a recursive call in the catch block until all the special characters are replaced. Have a look at the line in red.

Let’s go to the ReplaceSpecialChars() function. It creates a temp copy of the original xml file and does the character replacement with several number of IO operation. Think a scenario where we need to deal with an xml data that has some thousand line and each line has special character, we end up doing IO operation thousands of time. Wow what a logic.

Refactored Approach

I rewrote the logic, I used C# as my choice. My approach is simple, read the xml file then format it the way we need it and load it to XMLDocument. Let see my piece of code.

public XmlDocument LoadXMLDoc()
{
    XmlDocument doc = new XmlDocument();
    string xmlToLoad = this.ParseXMLFile();
    doc.LoadXml(xmlToLoad);
    return doc;
}
private string ParseXMLFile()
{
    StringBuilder formatedXML = new StringBuilder();
    StreamReader xmlReader = new StreamReader("CustomerData.xml");
    while (xmlReader.Peek() >= 0)
        formatedXML.Append(this.ReplaceSpecialChars(xmlReader.ReadLine()));
    return formatedXML.ToString();
}
private string ReplaceSpecialChars(string xmlData)
{
    int grtrPosAt = xmlData.IndexOf(">");
    int closePosAt = xmlData.IndexOf("</");
    int lenthToReplace = 0;
    if (grtrPosAt>closePosAt) return xmlData;

    lenthToReplace= (closePosAt<=0 && grtrPosAt<=0)?xmlData.Length:(closePosAt-grtrPosAt)-1;
    //get the string between xml element. e.g. <ContactName>Hanna Moos</ContactName>, 
    //you will get 'Hanna Moos'
    string data = xmlData.Substring(grtrPosAt + 1, lenthToReplace);
    string formattedData = data.Replace("&", "&amp;").Replace("<", "&lt;")
                               .Replace(">", "&gt;").Replace("'", "&apos;");
    xmlData = xmlData.Replace(data, formattedData);
    return xmlData;
}

I took reactive approach rather than waiting the XMLDocument to throw error and rectify it then try loading. ReplaceSpecialChars() function formats the xml string and return it. I spend just 10 minute to come up with this function, so may not be the best one but definitely better than what mentioned in KB article.

Point to note In my approach

  • The IO operation is only once, first time to read the xml file.
  • XMLDocument will get a clean formatted xml to do it’s operation.
  • No recursive call in catch block.
  • LOC is less, so easy to understand.

If you find any better approach, update that in the comment section.

Note: I send a feedback to Microsoft couple of weeks back about the issues in the code but no response yet.

Happy coding …..

Written by Sony Arouje

October 21, 2011 at 2:12 pm

WCF Duplex Communication with multiple clients

with 8 comments

Recent days I am working on a batch processing system to cater printing of more than 100k documents per day from a queue. To make system scalable I divided the system into two

Producer: who produce the document, it’s time consuming, CPU intensive process.
Consumer: who consumes the document and print/Email/fax it. Fairly simple with different handlers for printing, faxing or emailing and less CPU intensive

Producer and Consumer will communicate through a WCF service using TCPBinding.

One of the functionality of consumer is reporting the status (exception while printing) of the document back to the producer for audting purpose. My first design approach was
    Run these two system as a pair. The producer will call a WCF service hosted in consumer when a document is ready for printing and consumer will call a WCF service in producer to report the status.

If the document volume is high then user can configure and run multiple Producers and one consumer. That means each instance of producer, we need to provide unique endpoints. But producer can communicate to any one Consumer to status reporting thus by adding load to one of the Consumer.

If you think in terms of scalability/deployment you can visualize how complex the design will be. Yes I also realize that my design is ridiculous. To make it more scalable, I have to redesign the communication between the Consumer and the Producer.

This time I thought of trying Duplex communication for the first time. Initially I avoid duplex binding in first place because I don’t know it, second a bit scared of introducing complexity. In my mind duplex binding is complex and my approach I explained above is simple 🙂 (how ignorant I am).

So I decided to try duplex communication. But I need to evaluate it and don’t want to mess with my current implementation. So end up in writing a small tracer to experiment duplex communication. Rest of the post will go through the tracer I created.

Note: My design is surrounded with the proxy less communication approach.

Let’s start with the Service contract and Callback contract.

[ServiceContract (SessionMode=SessionMode.Required,CallbackContract=typeof(ICallbackInterface))]
public interface IServiceContract
{
    [OperationContract (IsOneWay=true)]
    void MessageToProcess(ServiceMessage message);
}

 

As you can see I mentioned the type of callback contract in ServiceContract attribute. The above contract will be implemented in Consumer and Producer will call the consumer using this contract if any thing available for processing.

public interface ICallbackInterface
{
    [OperationContract(IsOneWay=true)]
    void ProcessedMessage(ServiceMessage message);
}

The above callback interface will be implemented in Producer. Consumer will callback the Producer and update the status using this contract.

ServiceMessage is just a value object to transfer data between consumer and producer. It has just one string field called Message.

Let’s implement the Service contract in one of the class in Consumer.

[ServiceBehavior (InstanceContextMode=InstanceContextMode.PerSession)]
public class MessageProcessingService:IServiceContract 
{
    private ICallbackInterface GetCurrentCallback()
    {
        return OperationContext.Current.GetCallbackChannel<ICallbackInterface>();
    }
    public void MessageToProcess(ServiceMessage message)
    {
        ProcessRequest procRequest = new ProcessRequest(this.GetCurrentCallback(), message);
        ProcessQueue.Add(procRequest);
    }
}

 

We need to decorate the MessageProcessingService with ServiceBehavior attribute as shown above, we cannot set that in config file.

GetCurrentCallback function will return the callback instance that is part of the service call.

MessageToProcess function will be called by Producer once it produce some message to process. As you can see I created a new object of ProcessRequest  with callback instance and message then add the ProcessRequest instance to a queue. I will explain why we need queuing system.

Why we need a Queue?

Think of a scenario where there are multiple Producers and single consumer. The single consumer may not able to process all the message received from multiple producers in real time. So all the message will be queued along with the callback instance. Consumer will process the item in the queue one by one and notify the producer once the processing is done. With this implementation we can have n number of producers and one consumer.

Process Request class

public class ProcessRequest
{
    private readonly ICallbackInterface _callbackInterface;
    private readonly ServiceMessage _message;
    public ProcessRequest(ICallbackInterface callbackInterface, ServiceMessage message)
    {
        _callbackInterface = callbackInterface;
        _message = message;
    }

    public ICallbackInterface GetCallback()
    {
        return _callbackInterface;
    }

    public ServiceMessage GetMessage()
    {
        return _message;
    }
}

 

ProcessQueue implementation as follows

public static class ProcessQueue
{
    private static Queue<ProcessRequest> _processQueue;
    private static ManualResetEvent _enqueuedEvent;

    static ProcessQueue()
    {
        _processQueue = new Queue<ProcessRequest>();
        _enqueuedEvent = new ManualResetEvent(false);
    }

    public static void Add(ProcessRequest request)
    {
        lock (_processQueue)
        {
            _processQueue.Enqueue(request);
            _enqueuedEvent.Set();
        }
        ProcessQueuedItem();
    }

    private static ProcessRequest _currentRequest;
    public static bool Dequeue()
    {
        lock (_processQueue)
        {
            if (_processQueue.Count > 0)
            {
                _enqueuedEvent.Reset();
                _currentRequest = _processQueue.Dequeue();
                return true;
            }
            else
                return false;
        }
    }

    private static void ProcessQueuedItem()
    {
        while (Dequeue())
        {
            ServiceMessage message = _currentRequest.GetMessage();
            message.Message += " {Processed}";
            _currentRequest.GetCallback().ProcessedMessage(message);
        }
    }
}

 

ProcessedQueuedItem function process the message, for my tracer I just appended ‘{Processed}’ at the  message.

We are done with the Consumer implementation. Let’s go through the Producer.

public partial class frmProducer : Form
{
    public frmProducer()
    {
        InitializeComponent();
        this.Text = this.Text+ RandomGenerator.GetRandom().ToString();
    }

    private void btnSend_Click(object sender, EventArgs e)
    {
        ServiceMessage message = new ServiceMessage();
        message.Message = txtMessage.Text;
        InstanceContext instanceContext = new InstanceContext(new CallbackHandler());
        IServiceContract service = ServiceFactory.CreateInstance<IServiceContract>(instanceContext);
        service.MessageToProcess(message);
    }
}

 

As you can see in btnSend_click we need to create instance of InstanceContext with an instance of class that implemented ICallbackInterface I created earlier. Then I call a factory class to get the channel to Consumer. In the factory I used DuplexChannelFactory instead of ChannelFactory.

CallbackHandler implementation

public class CallbackHandler:ICallbackInterface
{
    public void ProcessedMessage(ServiceMessage message)
    {
        //do the status reporting here.
    }
}
 

We are done with our Producer and consumer implementation. We can test it by running different instance of Producer and one instance of consumer and see how the communication works.

Once my tracer is successful I redesigned the communication of Producer and Consumer in my projects with few changes of code. With new design user can add any number of Producer just by creating an instance of Producer without any difficulty.

Hope this little post will help some one who is new to duplex communication in WCF.

Download tracer source code (WCF.TCPIP.Duplex.Service) here

Written by Sony Arouje

September 29, 2011 at 1:56 am

ToStringHelper

with one comment

The implementation is inspired by Google Guava libraries. ToStringHelper is a simple class helps to get all the property values of a class in string format. Some times for logging purpose we may need the property values of entities, to achieve that we override ToString()  and append the required property values. ToStringHelper will ease this step.

In Guava libs, ToStringHelper is implemented as fluent APIs and user needs to provide the property and values as shown below.

return InstanceHelper.ToStringHelper(this).Add("Name", Name).Add("Age", Age).ToString();

 

I am very lazy of doing this way, so I used reflection to do my job. In the later part of this post you can see the implementation of ToStringHelper and how I get the value using reflection.

Let’s see the use of this helper method.

public class Student
{
    public Student(string name,string lastName, int age)
    {
        this.Name = name;
        this.Age = age;
        this.LastName = lastName;
    }
    [UseInToString(AliasName="Student Name")]
    public string Name { get; private set; }

    [UseInToString]
    public int Age { get; private set; }

    public string LastName { get; private set; }
    public override string ToString()
    {
        ToStringHelper toStrngHelper = new ToStringHelper("Student");
        toStrngHelper.Add<Student>(this);
        return toStrngHelper.ToString();
    }
}

Have a look at the above class. I override ToString() and called the ToStringHelper to provide a textual data. This way I can avoid all the repeated process of appending and returning the values from ToString function. In my scenario I don’t need all the value in the string returned by ToString. So I created a CustomAttribute called UseInToString, which ever the property decorated with UseInToString will be used in creating the string output. Also we can provide an AliasName for the property, if AliasName exist then AliasName will be used instead of Property name.

Let’s write a test and see whether out function works fine.

[TestCase]
public void TestInstanceHelper()
{
    Student student = new Student("Sony","Arouje",30);
    Assert.AreEqual("Student{Student Name: Sony, Age: 30}", student.ToString());
    Console.WriteLine(student.ToString());
}

No more description required for the above test case, the output is pretty much self explanatory.

Now let’s have a look at the ToStringHelper class and UseInToString custom attribute

[System.AttributeUsage(System.AttributeTargets.Property)]
public class UseInToString : System.Attribute
{
    private string _humanReadablePropertyName;
    public string AliasName 
    {
        get { return _humanReadablePropertyName; }
        set { _humanReadablePropertyName = value; }
    }
}

public class ToStringHelper
{
    StringBuilder _outPutValue = null;
    string _delimiter = string.Empty;
    public ToStringHelper(object instance)
    {
        _outPutValue = new StringBuilder
        (instance.GetType()==typeof(string)?instance.ToString():instance.GetType().Name);
        _outPutValue.Append("{");
    }
    private void Add(string name, object value)
    {
        _outPutValue.Append(string.Format("{0}{1}: {2}", _delimiter, name, value));
        _delimiter = ", ";
    }
    public override string ToString()
    {
        _outPutValue.Append("}");
        return _outPutValue.ToString();
    }

    public void Add<TClazz>(TClazz clazz) where TClazz : class
    {
        object propertyValue;
        typeof(TClazz).GetProperties().Where(pr => pr.CanRead).ToList()
        .ForEach(property =>
        {
            UseInToString useInAttr = (UseInToString)property.GetCustomAttributes(false)
                                           .FirstOrDefault(attr => attr is UseInToString);
            if (useInAttr != null)
            {
                propertyValue = property.GetValue(clazz, null);
                this.Add(string.IsNullOrEmpty(useInAttr.AliasName) ? property.Name 
                                              : useInAttr.AliasName, propertyValue);
            }
        });
        
    }
}

I think the class describes what it does. Hope you may find it useful. Happy coding…

Written by Sony Arouje

September 24, 2011 at 2:50 am

Posted in .NET

Tagged with , ,

Persist Domain Model using NHibernate

with 2 comments

Last couple of days I was spending time with NHibernate. I went through several articles and books related to NHibernate. I learned bits and pieces about hibernate, next step for me is to implement what ever I learned so far. I choose a small Sales Tax problem for learning NH.

Object Relational Mappers are best suited in Object oriented development (OOD). In OOD process the designer first implement the domain model based on the business requirement. Then use any ORM to persist. In this approach we are giving importance to domain model then comes the db modelling. Domain model and NHibernate will go hand in hand. A designer can design the domain model without thinking much about persistence. Anyway I am not going much in detail of Domain models, you all can read more from Patterns of Enterprise Application Architecture and Domain-Driven Design: Tackling Complexity in the Heart of Software

Below is the rough diagram of domain model I created

image

Let’s go through Order Entity

namespace DDD.DomainModel
{
    public class Order
    {
        private IList<OrderLine> _lineItems;
        private Customer _customer;
        private ISalesTaxCalculator _salesCalculator;
        private int _orderId;

        private Order() 
        {

        } 
        public Order(Customer customer, ISalesTaxCalculator salesCalculator)
        {
            this._customer = customer;
            this._lineItems = new List<OrderLine>();
            this._salesCalculator = salesCalculator;
        }

        public int OrderId
        {
            get { return _orderId; }
        }
        public Order With(OrderLine orderLine)
        {
            Money tax = _salesCalculator.CalculateTax(orderLine);
            orderLine.SetTaxAmount(tax);
            orderLine.SetOrder(this);
            _lineItems.Add(orderLine);
            return this;
        }
        public Money GetTotalTax()
        {
            Money totalTax = Money.Empty();
            for (int i = 0; i < _lineItems.Count; i++)
                totalTax += _lineItems[i].GetTaxAmount();
            return totalTax;
        }
        public Money GetGrandTotal()
        {
            Money total = Money.Empty();
            for (int i = 0; i < _lineItems.Count; i++)
                total += _lineItems[i].GetSubTotal();
            return total;
        }
        
        public int GetNumberOfItems()
        {
            return this._lineItems.Count();
        }
        public virtual IList<OrderLine> LineItems
        {
            get { return _lineItems; }
        }
        public Customer Customer
        {
            get
            {
                return _customer;
            }
        }

    }
}

 

As you could see in the order class there is no Getter/Setter properties for setting the data from db. One of the good feature of NHibernate is, it can set or get data from private fields via reflection. It helps us to maintain Immutability in entities.

Mapping File

Hibernate uses xml configuration files to map Entities to database tables. Let’s see the configuration file for Order entity.

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping default-access="field"
    xmlns="urn:nhibernate-mapping-2.2"
    auto-import="true">
  <class name="DDD.DomainModel.Order,DDD.DomainModel"  lazy="false" table="[Order]">
    <id name="OrderId" column="order_id" access="nosetter.camelcase-underscore">
      <generator class="native"></generator>
    </id>
    <bag
      name="LineItems"
      cascade="all-delete-orphan" access="nosetter.camelcase-underscore" lazy="true">
      <key column ="order_id"/>
      <one-to-many class ="DDD.DomainModel.OrderLine,DDD.DomainModel"/>
    </bag>
    <many-to-one name="Customer" column="customer_id" not-null="false" cascade="none" 
       access="nosetter.camelcase-underscore" update="false" 
       class="DDD.DomainModel.Customer,DDD.DomainModel"/>
  </class>
</hibernate-mapping>

Let’s go through the config file

In the class tag, I mapped the Order class with the database table Order. Inside the class tag provide the mappings for the fields to the table row.

id tag tells hibernate that the field is an Identity field, here I mapped _orderId to column order_id. So what is this access property. It will directs the hibernate from where to get/set the value. Here I set as nosetter.camelcase-underscore. I explain that part later.

Bag tag tells hibernate that LineItems is a collection. Inside bag we define the relationship with orderline.

Access Attribute

Hibernate can set value to private fields or to property. Hibernate uses ‘access’ attribute to determine this.

field: Set access to field (access=’field’) directs hibernate to read values from private field during persisting and while fetching it sets the private field with the value from database. I feel it’s a very important feature, this makes objects hides the data and exposed through predefined interfaces.

property: Set access to property (access=’property’) directs hibernate to get and set values to the properties.

nosetter.*: Set access to property (access=’nosetter’) directs hibernate to get values from property of the field mentioned but set value to private field. Let’s explain with an e.g.

private Customer _customer;
public Customer Customer { get { return _customer; } }
In xml we configure like
<many-to-one name="Customer" column="customer_id" not-null="false" cascade="none" access="nosetter.camelcase-underscore" …./>

 

This tells hibernate while persisting get the value from the Customer property but while setting the value from db uses the variable field (with same name as property) in camelcase-underscore format, here it will set the value to _customer.

You all can see the rest of the configuration in the source code.

Hibernate Repository

I created a generic repository for Hibernate just like the one I created for Entity Framework. Let’s go through the hibernate repository.

public class HibernateRepo:IRepository
{
    IList _itemsAdded = new System.Collections.ArrayList();
    ISession _session;

    private static ISessionFactory CreateSessionFactory()
    {
        Configuration cfg = new Configuration().Configure();
        return cfg.BuildSessionFactory();
    }

    private ISession Session
    {
        get 
        {
            if (_session!=null && _session.Connection.State != System.Data.ConnectionState.Open)
            {
                _session.Connection.Close();
                _session.Connection.Open();
            }
            if (_session == null || _session.IsOpen == false)
                _session = CreateSessionFactory().OpenSession();
            
            return _session;
        }
    }

    ITransaction _currentTransaction = null;
    public void BeginTransaction()
    {
        _currentTransaction= this.Session.BeginTransaction();
    }
    public void CommitTransaction()
    {
        if (_currentTransaction != null)
            _currentTransaction.Commit();
    }
    public void Rollback()
    {
        if(_currentTransaction!=null)
            _currentTransaction.Rollback();
    }

   
    public IQueryable<TEntity> GetQuery<TEntity>() where TEntity : class
    {
        return this.Session.Query<TEntity>();
    }

    public IList<TEntity> GetAll<TEntity>() where TEntity : class
    {
        return this.GetQuery<TEntity>().AsEnumerable<TEntity>().ToList();
    }

    public IList<TEntity> Find<TEntity>(System.Linq.Expressions.Expression<Func<TEntity, bool>> criteria) where TEntity : class
    {
        IList<TEntity> entities= this.GetQuery<TEntity>().Where(criteria).ToList();
        NHibernateUtil.Initialize(entities);
        return entities;
    }

    public TEntity Single<TEntity>(System.Linq.Expressions.Expression<Func<TEntity, bool>> criteria) where TEntity : class
    {
        TEntity entity= this.GetQuery<TEntity>().SingleOrDefault<TEntity>(criteria);
        return entity;
    }

    public TEntity First<TEntity>(System.Linq.Expressions.Expression<Func<TEntity, bool>> criteria) where TEntity : class
    {
        TEntity entity = this.GetQuery<TEntity>().FirstOrDefault<TEntity>(criteria);
        return entity;
    }

    public void Add<TEntity>(TEntity entity) where TEntity : class
    {
        _itemsAdded.Add(entity);
    }

    public void Delete<TEntity>(TEntity entity) where TEntity : class
    {
        this.Session.Delete(entity);
    }

    public void Delete<TEntity>(IEnumerable<TEntity> entites) where TEntity : class
    {
        throw new NotImplementedException();
    }

    public void SaveChanges()
    {
        for (int i = 0; i < _itemsAdded.Count; i++)
        {
            this.Session.SaveOrUpdate(_itemsAdded[i]);
        }
    }

    public void Dispose()
    {
        if (this.Session != null)
        {
            _session.Close();
            _session.Dispose();
        }
        if (this._currentTransaction != null)
            _currentTransaction.Dispose();
    }
}

 

Most of the functions are same as the one I created for EF. Let’s go through some function I added for hibernate.

You might wonder why there is no connection string mentioned in this class, also there is no reference about the mapping xml files. How hibernate get all these information? Hibernate uses a configuration file called ‘hibernate.cfg.xml’. This file should exist in the bin folder. This file is not mandatory, you can directly give all the information to hibernation while creating session. Let’s see the configuration file

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
  <session-factory>
    <property name="connection.provider">
      NHibernate.Connection.DriverConnectionProvider
    </property>

    <property name="connection.driver_class">
      NHibernate.Driver.SqlClientDriver
    </property>
    <property name="connection.connection_string">
      Data Source=PROLAPE00700\SQLSERVER;Initial Catalog=SASales;
      Persist Security Info=True;User ID=sony;pwd=sony
    </property>
    <property name="proxyfactory.factory_class">
       NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle
    </property>
    <property name="dialect">
      NHibernate.Dialect.MsSql2008Dialect
    </property>
    <mapping assembly="DDD.Infrastructure.Persistance"/>
  </session-factory>
</hibernate-configuration>

 

I configured connection string and mapping assembly here. Hibernate uses mapping assembly tag to find out here the mapping files located and it fetches from the assembly using reflection. One thing to remember is the mapping files Build Action should be Embedded Resource.

How this configuration file get passed to hibernate? Have a look at the static function in the repository called CreateSesstionFactory().

private static ISessionFactory CreateSessionFactory()
{
    Configuration cfg = new Configuration().Configure();
    return cfg.BuildSessionFactory();
}

When we call Configuration().Configure() hibernate search for the above configuration file and uses the settings in the file to configure the session.

Once you go through the source you might understand how easy we can persist out domain models with less effort.

Download Source Code

Written by Sony Arouje

June 24, 2011 at 8:35 pm

Entity Framework Vs NHibernate

with 2 comments

I worked on EF POCO model for some times and I come across with several stopovers. EF doesn’t have a very good error reporting, it will just throw some error and we need to run pillar to post to find out why on earth we are getting this error. Another issue is working in disconnected mode, I will explain in detail later in this post. For testing I used EF CTP5, hopefully things might have improved in the latest release.

After dating with EF for quiet some time, I realized that EF is not matured enough to hang around with, it’s still evolving and need time. I thought I need to look around and see any other beautiful and healthy ORM’s around. Yes I do aware of NHibernate a powerful ORM in the market for quiet a long period. So I decided to see in depth. I decided to write a small app to compare both ORM’s. For my comparison I used FluentNHibernate, I like to map my entities to table using code rather than an xml.

I haven’t completed the comparison yet. One of the important focus of my test is how CRUD operation works in disconnected model. In connected model the context can keep track of the changes and do the necessary Create/Update/Delete operation without much issue. So my test app have a WCF service to supply data to presentation layer.

First Test

The presentation layer issue a search request and get an author object from the WCF service, make some changes to author data and send it back to service for persisting it.

Entity Framework: Presentation layer get author object, did some changes to First Name. Sent the modified object to Service for persisting. In the persistence layer attached the author object to ObjectContext and called SaveChanges(). But nothing happened, EF couldn’t recognize the changes made to the object and didn’t persist the changes.

NHibernate: Presentation layer get author object, did some changes to First Name. Sent the modified object to Service for persisting. In the persistence layer make a call to SaveOrUpdate() of Session object with the modified entity. I could see that the changes get persisted to the db.

Test Summary

In my first test I could see that update operation in disconnected  mode is pretty easy in NHibernate than EF. I am not sure whether am doing some thing wrong in EF thus it’s not persisting. But from a devs stand point we really don’t want to do much stuffs with an ORM to persist any changes. It’s ORM’s headache to figure out whether the entity state is dirty or not, if dirty then update it.

After this small test I feel like I need to embrace NHibernate as my ORM. Also one of the good feature of NHibernate is it’s error reporting. NH will report error with sql statement it issued to db, it will be helpful for a dev to analyze the error and take necessary actions.

EF might be strong in Autogenerated code, with EDMX, blah, blah. But not yet matured enough to support POCO model. In my point of view NHibernate is the right ORM to choose in comparison with Entity Framework, if you are serious in POCO model.

Note: NHibernate uses lazy loading extensively and you may have some trouble in WCF side while serializing it. It’s advisable to use DTO to transfer data between layers. Trent Foley have a nice post to explain how to perform eager loading with NHibernate.

This is just an initial test and I will move forward to test different scenarios. If I get time I will post the results in future posts.

Overview of Test Application

The test application consist of Presention layer (Winform), WCF service, Domain model and Persistence layer. The service layer and the persistence layer is loosely coupled. At any point of time Service layer doesn’t know to whom he is interacting, it can be EF repository instance or NH instance, I achieved it by Caste Windsor IOC. This loosely coupled approach help me to compare both ORM without any single code change rather with a xml configuration change.

For the test app I used Pubs database. One of domain entity is shown below.

namespace ORM.Domain
{
    [DataContract]
    public class Author
    {
        [DataMember]
        public virtual string Id { get; private set; }
        [DataMember]
        public virtual string LastName { get; set; }
        [DataMember]
        public virtual string FirstName { get; set; }
        [DataMember]
        public virtual string Phone { get; set; }
        [DataMember]
        public virtual string Address { get; set; }
        [DataMember]
        public virtual IList<Titles> TitlesAuthored { get; set; }
        public virtual bool Contract { get; set; }

        public Author()
        {
            this.TitlesAuthored = new List<Titles>();
        }
        public virtual void AddTitles(Titles titles)
        {
            this.TitlesAuthored.Add(titles);
            titles.Authors.Add(this);
        }
    }

It’s just a anemic entity without much responsibility. Anyway my focus is not in DDD, so just bare with my entity structure.

Now I need to map my entity to Author table. I used fluent API’s of the ORM to do the mapping.

Entity Framework Mapping

public class AuthorConfiguration:EntityTypeConfiguration<Author>
{
    public AuthorConfiguration()
    {
        HasKey(a => a.Id);
        HasMany(a => a.TitlesAuthored);
        Property(a => a.Id).HasColumnName("au_id");
        Property(a => a.Address).HasColumnName("address");
        Property(a => a.FirstName).HasColumnName("au_fname");
        Property(a => a.LastName).HasColumnName("au_lname");
        Property(a => a.Phone).HasColumnName("phone");
        Property(a => a.Contract).HasColumnName("contract");
        ToTable("dbo.authors");
    }
}

FluentHibernate Mapping

public class AuthorMap:ClassMap<Author>
{
    public AuthorMap()
    {
        Id(x => x.Id,"au_id");
        Map(x => x.LastName, "au_lname");
        Map(x => x.FirstName, "au_fname");
        Map(x => x.Address, "address");
        Map(x => x.Phone, "phone");
        Map(x => x.Contract, "contract");
        HasManyToMany(t => t.TitlesAuthored).Cascade.All().Table("titleauthor")
                           .ChildKeyColumn("title_id")
                           .ParentKeyColumn("au_id");Table("dbo.authors");
    }
}

What ever I posted here is just my findings. Don’t consider this as a benchmark. You better consider your scenarios and do a small tracer and find out which suites your requirement. Pay careful attention before deciding on any ORM else you will suffer later.

I think it’s better to stop here, you all can look into my source code for more details. I uploaded my test application to Sky drive, if interested pls have a look at it.

Download Source code

Written by Sony Arouje

May 26, 2011 at 7:48 pm

Chain of Responsibility pattern with Dependency Injection

with 11 comments

Recently one of my friend asked me for a suggestion while preparing for an interview. The problem was, to find what kind of triangle by passing three values, whether it’s Equilateral or Isosceles, etc. He wanted to implement a scalable approach, that means adding a new type of triangle with minimal code change. First approach came to my mind is Iterator pattern, I ruled out that pattern immediately as it needs code change, if we want to add a new triangle. Next approach came to my mind is Chain of Responsibility, if we combine this pattern with Dependency Injection then will have room for scalability.

For demonstration I used Castle Windsor Inversion of Control container. I can add new triangles with minimal or no code change if we use IOC containers. We can add new triangles just by adding new component to the configuration file.

What is Chain of Responsibility?  It’s like a quiz competition, if one team is not able to answer the question then pass it to another team. You can find more about Chain of Responsibility here . One main advantage of this approach is low coupling and orthogonal.

I used Chain of Responsibility to solve the Triangle problem. I have several type of Triangle class derived from ITriangle interface and stitched together using Castle Windsor. The values will passed to the first Triangle instance, if the first triangle instance can handle it, then return the result other wise pass the values to the next instance in the chain.

Let’s see the implementation.

public interface ITriangle
{
    string Execute(int x, int y, int z);
    void Add(ITriangle triangle);
}

 

Different Triangle Implementation

public class EquilateralTriangle:ITriangle
{
    private ITriangle _triangle=null;
    public EquilateralTriangle(ITriangle nextTriangle)
    {
        _triangle = nextTriangle;
    }
    public string Execute(int x, int y, int z)
    {
        int average = (x + y + z) / 3;
        if (average == x)
            return this.ToString();
        else
        {
            if(_triangle!=null)
                return _triangle.Execute(x, y, z);
        }

        return string.Empty;
    }

    public void Add(ITriangle triangle)
    {
        _triangle = triangle;
    }

    public override string ToString()
    {
        return "Equilateral Triangle";
    }
}

 

public class IsoscelesTriangle : ITriangle
{
    public IsoscelesTriangle (ITriangle nextTriangle)
    {
        _triangle = nextTriangle;
    }
    public IsoscelesTriangle() { }
    private ITriangle _triangle = null;
    public string Execute(int x, int y, int z)
    {
        int average1 = (x + y) / 2;
        int average2 = (y + z) / 2;
        int average3 = (x + z) / 2;
        if (average1 == x || average2 == y || average3 == z)
            return this.ToString();
        else
        {
            if (_triangle != null)
                return _triangle.Execute(x,y,z);
        }
        return string.Empty;
    }

    public void Add(ITriangle triangle)
    {
        _triangle = triangle;
    }
    public override string ToString()
    {
        return "Isosceles Triangle";
    }
}

 

So now I have two different type of Triangles. Both implementation check the values and if it satisfies then return the name other wise pass it to the chain.

Let’s see how can we call this

ITriangle isoscelesTriangle = new IsoscelesTriangle();
ITriangle head = new EquilateralTriangle(isoscelesTriangle);
Console.WriteLine(head.Execute(10,10,10));
Console.WriteLine(head.Execute(11,11,20));

 

The output will be

Equilateral Triangle
Isosceles Triangle

Here is one problem, if I want to add a new Triangle then I have to modify the code here. So how to make it scalable with no code change. Let’s see how we can scale it using an IOC Container. As I told earlier I am going to use Castle Windsor here.

We can use Fluent API or XML configuration to configure our components. Here I used XML for configuration. Let’s go through xml configuration file

<configuration>
  <components>
    <component id="IsoscelesTriangle"
      service="Triangles.IsoscelesTriangle, Triangles"
      type="Triangles.IsoscelesTriangle, Triangles">     
    </component>    
    <component id="Equilateral"
          service="Triangles.ITriangle, Triangles"
          type="Triangles.EquilateralTriangle, Triangles">
      <parameters>
        <nextTriangle>${IsoscelesTriangle}</nextTriangle>
      </parameters>
    </component>
  </components>
</configuration>

 

Have a look at the component with id Equilateral, I mentioned the interface and class that implements it. Also you can notice some thing called parameters, their I pass the constructor’s parameter. Here I directed castle to pass the instance of IsoscelesTriangle.

In Component IsoscelesTriangle we dont have any parameters, in this scenario it uses the default constructor.

Next step, we need to pass this configuration file to castle. Bellow code explains it.

public static class Ioc
{
    private static IWindsorContainer _container = null;
    public static T Resolve<T>() where T : class
    {
        InitializeWindsorContainer();
        return _container.Resolve<T>();
    }

    private static void InitializeWindsorContainer()
    {
        try
        {
            if (_container == null)
            {
                StringBuilder basePath = new StringBuilder(AppDomain.CurrentDomain.BaseDirectory);
                basePath.Append(@"IocConfiguration.xml");
                _container = new WindsorContainer(new XmlInterpreter(basePath.ToString()));
            }
        }
        catch (Exception ex)
        {
            throw;
        }
    }
}

Now we completed our IOC and configuration. Let’s see how I find the triangle now.

ITriangle head = Ioc.Resolve<ITriangle>();
Console.WriteLine(head.Execute(10,10,10));
Console.WriteLine(head.Execute(11,11,20));

 

Previously I created Isosceles Triangle instance then create Equilateral instance and pass Isosceles instance through constructor. In the above scenario, castle will create Equilateral instance by creating and passing Isosceles instance. So we are completely freed of creating the chains.

How can we add a new traingle? It’s very simple, first create a new triangle class derived from ITriangle as shown below.

public class XTriangle:ITriangle
{
    ITriangle _triangle;
    public XTriangle(){}

    public XTriangle(ITriangle nextTriangle)
    {
        _triangle = nextTriangle;
    }

    public string Execute(int x, int y, int z)
    {
        if (x > y)
        {
            return this.ToString();
        }
        else
        {
            if (this._triangle != null)
                return _triangle.Execute(x, y, z);
        }
        return null;
    }

    public void Add(ITriangle triangle)
    {
        throw new NotImplementedException();
    }
}

 

I need to plug this new Triangle to the chain, it’s as simple as modifying the configuration file as shown below.

Note: There is no triangle called XTriangle, just for demo I created a class.

<configuration>
  <components>
    <component id="XTriangle"
    service="Triangles.XTriangle, Triangles"
    type="Triangles.XTriangle, Triangles">
    </component>

    <component id="IsoscelesTriangle"
      service="Triangles.IsoscelesTriangle, Triangles"
      type="Triangles.IsoscelesTriangle, Triangles">
      <parameters>
        <nextTriangle>${XTriangle}</nextTriangle>
      </parameters>      
    </component>
    
    <component id="Equilateral"
          service="Triangles.ITriangle, Triangles"
          type="Triangles.EquilateralTriangle, Triangles">
      <parameters>
        <nextTriangle>${IsoscelesTriangle}</nextTriangle>
      </parameters>
    </component>
  </components>
</configuration>

I made some changes and I marked those changes in Bold Italics. Let’s execute the project once again. As per the configuration the new XTriangle will get added to Isocles Triangle. Now the chain look like

Equilateral Triangle->Isosceles Triangle->XTriangle->[END OF CHAIN]

ITriangle head = Ioc.Resolve<ITriangle>();
Console.WriteLine(head.Execute(10,10,10));
Console.WriteLine(head.Execute(11,11,20));
Console.WriteLine(head.Execute(20, 3, 10));

 

The out put will be

Equilateral Triangle
Isosceles Triangle
Triangles.XTriangle
 

We added a new triangle to the chain with little code change.

Summary

With a mix of patterns we can build a scalable, low coupled system that can maintain very easily. Happy coding…

 

Download the Code

Written by Sony Arouje

April 6, 2011 at 4:32 pm

Hosting Pipe/TCP based WCF service in Windows Activation Service

with 8 comments

In this post I will give a brief idea of how to host pipe/TCP based WCF service using WAS. Before WAS, we host TCP/pipe based service using custom hosting. That means we need to write an application ourself to host our services. Including me most of the deves wrote applications to host WCF services, so am not going in detail of custom hosting.

What’s WAS or Windows Process Activation services? WAS is part of IIS that enable us to host non http based services. I am not going much details of WAS. Here I am more concentrating on how to configure WAS and run a small test application.

Configure WAS in our System

By default WAS will be disabled. We need to enable it our self, let’s see how we can do that.

1. Goto control panels –> Programs and Features. Click on ‘Turn Windows Feature on or off’ link. It will open a window as shown below. From the list select Windows Process Activation Service and make sure all the child elements also selected.

image

2. Also scroll up and Select ‘Microsoft .NET Framework 3.xxx’ as shown below. Make sure all the child elements also selected, if not select it.

image

We enabled Windows Activation Service in our system. Let’s go ahead and create a WCF service.

For testing purpose I created a WCF service to add two numbers. Let’s see the service configuration

  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="false"/>          
        </behavior>
        <behavior name="calcServiceBehaviour">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
          <dataContractSerializer maxItemsInObjectGraph="2147483647"/>
        </behavior>    
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
    <services>
      <service name="ServiceLayer.CalculatorService" behaviorConfiguration ="calcServiceBehaviour">
        <endpoint name="CalculatorService" address="" binding="netTcpBinding"
                  contract="ServiceLayer.ICalc" />
        <endpoint name="CalculatorService" address="" binding="basicHttpBinding"
          contract="ServiceLayer.ICalc" />
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
      </service>
    </services>
  </system.serviceModel>

As you can see I have two endpoints HTTP and TCP. If we host this in IIS and try to browse it will throw error. Still some configuration is left behind. Let’s finish that config too.

Goto IIS configuration file. You can find that in C:\Windows\System32\inetsrv\config. Open applicationHost.config in notepad. You can see the screen shot below.

image

Search for bindings, and you can see the marked section as shown above. By default you could only see HTTP binding and rest of the binding you can add it. If other binding exist then we are good. If not copy paste the below bindings to the config file under Bindings section.

<binding protocol="net.tcp" bindingInformation="808:*" />

<binding protocol="net.pipe" bindingInformation="*" />

<binding protocol="net.msmq" bindingInformation="localhost" />

<binding protocol="msmq.formatname" bindingInformation="localhost" />

Next step is create an application in IIS. I named the application as Calculator. Right click on the newly created Application and select Manage Application –> Advanced Settings…, you will get a popup as shown below

image

In the above popup you need to enable the protocol this application going to support. As you can see the marked section, I added http, pipe and tcp protocols for my Calculator service. We can enter the protocols like http,net.pipe,net.tcp (separated by comma).

Once again go back to applicationHost.config file and verify the Sites section. You can see the newly created site with protocols it supports. See the screen shot below

image

We are done with our configuration and the service is ready. Lets go ahead and browse our svc file. If it’s not throwing any error then we are good to go.

Note: If we install IIS after the installation of Visual studio then it will throw some an error like Error 500.21 Handler "svc-Integrated" has a bad module "ManagedPipelineHandler" in its module list". If you are getting this error then run aspnet_regiis.exe –i  in VS command prompt.

Create an application to test our service, I created a winform app to test it. Also we need to create a proxy to access the service. We can create the proxy using svcutil. The util will create a config file as well as shown below.

  <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="CalculatorService1" closeTimeout="00:01:00" openTimeout="00:01:00"
            receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false"
            bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
            maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
            messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
            useDefaultWebProxy="true">
          <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
              maxBytesPerRead="4096" maxNameTableCharCount="16384" />
          <security mode="None">
            <transport clientCredentialType="None" proxyCredentialType="None"
                realm="" />
            <message clientCredentialType="UserName" algorithmSuite="Default" />
          </security>
        </binding>
      </basicHttpBinding>
      <netTcpBinding>
        <binding name="CalculatorService" closeTimeout="00:01:00" openTimeout="00:01:00"
            receiveTimeout="00:10:00" sendTimeout="00:01:00" transactionFlow="false"
            transferMode="Buffered" transactionProtocol="OleTransactions"
            hostNameComparisonMode="StrongWildcard" listenBacklog="10"
            maxBufferPoolSize="524288" maxBufferSize="65536" maxConnections="10"
            maxReceivedMessageSize="65536">
          <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
              maxBytesPerRead="4096" maxNameTableCharCount="16384" />
          <reliableSession ordered="true" inactivityTimeout="00:10:00"
              enabled="false" />
          <security mode="Transport">
            <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />
            <message clientCredentialType="Windows" />
          </security>
        </binding>
      </netTcpBinding>
    </bindings>
    <client>
      <endpoint address="net.tcp://sonyarouje/Calculator/CalculatorService.svc"
          binding="netTcpBinding" bindingConfiguration="CalculatorService"
          contract="ICalc" name="CalculatorService">
        <identity>
          <servicePrincipalName value="host/sonyarouje" />
        </identity>
      </endpoint>
      <endpoint address="http://localhost/Calculator/CalculatorService.svc"
          binding="basicHttpBinding" bindingConfiguration="CalculatorService1"
          contract="ICalc" name="CalculatorService1" />
    </client>
  </system.serviceModel>

 

Add an app.config to our test app and copy paste the config generated by svcutil. As you can see we have two endpoint http and tcp and we can use any of those. I called the service in button click and the code is as follows

CalcClient calc = new CalcClient("CalculatorService");
int x = Convert.ToInt32(txtX.Text);
int y = Convert.ToInt32(txtY.Text);
MessageBox.Show (string.Format("Sum is {0}", calc.Sum(x,y )));
calc.Close();

While creating the object of service proxy we can pass the endpoint name. Here I am passing CalculatorService and it is the name of tcp endpoint. So the communication will establish through TCP. If we pass CalculatorService1 it will use the http end point.

Hope my post will be helpful for some one. if any Comments or Suggestion, pls post it in the comment section.

Download Test Projects

Written by Sony Arouje

April 3, 2011 at 3:19 pm

Posted in .NET, WCF

Tagged with , , , ,

Asynchronous Messaging in iTraveller

with 2 comments

Download iTraveller

I decided to use Lucene.Net to implement Search functionality in iTraveller. But the main design constrain was how to implement the indexing process without affecting the performance of any other functionality. Below are my use cases

  • Should start indexing asynchronously, no other process like Insert/Update should wait to complete indexing.
  • Other process like Insert/Update send a message to Indexing process and continue without waiting to finish the indexing process.
  • Lucene.Net will apply lock before start indexing. So only one process can access the Lucene.Net indexing API at a time.
  • Should have a single entry point for other process to invoke indexing.
  • Before indexing remove the record (if exist) from Index file.
  • Gather all the data related to photo like Photo Title, Description, Comments, etc. Index the data using Lucene.Net

In the above points, the first  one is the important thing I wanted to achieve to make iTraveller running smoothly. It’s obvious that I have to implement threading, and started my search for a thread safe queuing approach. At last I decided to use ‘Queue’ in System.Collections.Generic namespace. Let’s go through how I implemented message queue in iTraveller.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.IO;
using ITraveller.Domain;
using ITraveller.Utils.Logging;
namespace ITraveller.Indexer
{
    public class IndexQueue
    {
        private static Queue<Photo> _queue;
        private static ManualResetEvent _enqueuedEvent;
        private static Thread _workerThread;
        private static Photo _currentPhoto;
        private static ILogger _logger;
        static IndexQueue()
        {
            _queue = new Queue<Photo>();
            _logger = Logger.DefaultLogger;
            _enqueuedEvent = new ManualResetEvent(false);
            _workerThread = new Thread(new ThreadStart(PerformIndex));
            _workerThread.Start();
        }
        public static void RestartThread()
        {
            if (_workerThread.ThreadState == ThreadState.Stopped)
            {
                _workerThread.Abort();
                _workerThread = new Thread(new ThreadStart(PerformIndex));
                _workerThread.Start();
            }
        }
        public static void Add(Photo photo)
        {
            try
            {
                if (_queue == null)
                    _queue = new Queue<Photo>();
                lock (_queue)
                {
                    _queue.Enqueue(photo);
                    _enqueuedEvent.Set();
                }
                RestartThread();
            }
            catch (Exception ex)
            {
                _logger.LogInfo("Error while Adding to index Queue");
                _logger.LogError(ex);
            }
        }
        public static void Add(List<Photo> photos)
        {
            if (_queue == null)
                _queue = new Queue<Photo>();
            for (int i = 0; i < photos.Count; i++)
            {
                try
                {
                    lock (_queue)
                    {
                        _queue.Enqueue(photos[i]);
                        _enqueuedEvent.Set();
                    }
                }
                catch (Exception ex)
                {
                    _logger.LogInfo("Error while Adding to index Queue in loop");
                    _logger.LogError(ex);
                }
            }
            RestartThread();
        }
        private static bool Dequeue()
        {
            lock (_queue)
            {
                if (_queue.Count > 0)
                {
                    _enqueuedEvent.Reset();
                    _currentPhoto = _queue.Dequeue();
                }
                else
                {
                    return false;
                }

                return true;
            }
        }

        private static void PerformIndex()
        {
            IndexWriter writer=null;
            try
            {
                writer = new IndexWriter("./SearchIndex");
                while (Dequeue())
                {
                    IndexData indexData = new IndexData();
                    writer.DeleteFromIndex("ImageId:" + _currentPhoto.ImageID.ToString());
                    writer.WriteToIndex(indexData.GetIndexingData(_currentPhoto));
                }
            }
            catch (Exception ex)
            {
                _logger.LogInfo("Error while indexing data in worker thread");
                _logger.LogError(ex);
            }
            finally
            {
                if(writer!=null)
                    writer.Dispose();
            }
        }
    }
}

Other process can add Photo entity for indexing just by calling the static Add function and pass the required Photo( s ) object as parameter. Once the photo got added to queue, the Add function will call RestartThread function. The RestartThread function will check whether the worker thread Stopped, if Stopped then Recreate and Start the thread.

The function PerformIndex will get called when the worker thread starts. The PerformIndex function will dequeue the photo one by one from the Queue. Once the photo is dequeued successfully then one helper class will create and format the data for indexing and then  pass it to Lucene.Net class for further processing. The dequeue process will remove the photo object from the queue as well.

With the above approach I achieved a complete asynchronous messaging system. Any suggestion or better approach is always welcome.

Written by Sony Arouje

February 21, 2011 at 6:30 pm