Drupal 8 Configuration Management Issues


Everyone seems very excited with new configuration management tools provided by drupal 8. It just packages all (or single) site settings and you can import it to your other environments. But there are few glitches those can give developers hard time. And I am one of those developer. Here are few issues, I noticed while working with other developers and using configuration management.

1. Unable to install the standard module since it does not exist.

First of all, I had no idea what’s going on here. Later I figured out that, one of the developer installed fresh drupal  with standard profile and later changed the site hash to match the old installation. Now as configuration is looking for standard extension which does not exist on our site and configuration import fails with message ‘unable to install the standard….’. There are two ways to fix this issue:

  1. Make backup of you configuration files. Copy to your imported configuration files to your config folder and edit ‘core.extension.yml’. Remove the line standard: xxxx under module. Now, you can sync the config.
  2. Edit settings.php file, and paste:
$settings['install_profile']  = 'standard';

I would recommend to try first method and second if first does not work.

2. Configuration source control issue

When you install drupal, you will get weird directories. If you want to have common folder for configuration sync, you can define the directory where you want to have all config files. I personally prefer to use ‘sites/xxxx/sync’ folder. To use it as sync folder, you need to make add line of setting in settings.php.

$config_directories['active'] = 'sites/xxxx/sync'; //xxxx is your site folder, default in most of the cases

3. Configuration Management vs features

As you have noticed, features module is still there even drupal 8 is armed with configuration management. Features team has their own explanation on why you still need feature. As a rule of thumb, if you want to package certain collection of feature which you can use in other sites easily, you need features module. For example, If you want to use all articles related configurations in different site, you need feature in this case. You can use configuration management too but that will too much work. Using feature you can easily package them and import them in new site. You can learn details of configuration management vs features. https://www.youtube.com/watch?v=a6QLTjSFVhs and http://www.slideshare.net/nuvoleweb/2015-04devdaysmontpellier

 

 

Drupal: Use custom template file for any form


Introduction

Drupal 7 has well known template file concept. Template (.tpl) file is used to display the data and has minimal or no logic at all. I am pretty sure there are many scenarios where you would like to use your own template file. Most of the cases you can easily create template file using well documented instructions. For example, if you want to create template file for content type ‘Article’, you simply create a template file ‘node–article.tpl.php’ and put it inside your theme’s template folder. Drupal will automatically detects that template file and use it instead of default node.tpl.php. Similarly you can see theme suggestion of views just clicking on advanced->theme. But there are certain scenario where there is straight way to create and utilize template file. For example, you may want to customize login screen of your site and want to change layout or add more classes or add new div wrapper. To make use of template file in such scenario, we need to implement certain hooks.

Steps

First you need to add YOURTHEME_theme hook function in you theme->template.php file.

/**
 * theme_theme hook
 * @return type
 */
function MYTHEME_theme() {
    return array(
        'user_login' => array(
            'render element' => 'form',
            'path' => DIRECTORY_PATH_WHERE_YOU_WANT_TEMPLATE_FILE,
            'template' => 'user-login',
            'preprocess functions' => array('MY_FORM_PREPROCESS'),
        ),
    );
}

Now, if you want to update form data or add your own logic, you can use your preprocess function. Moreover, you can define your own custom variables which will be available to use in your template file. In the example below, I am creating new variable ‘myvariable’ which I can use in my template file later.

function MY_FORM_PREPROCESS(&$vars) {
    // Here you can have your own logic and 
    // you can define your own variables 
    // which will be available for you in your tpl file
    $vars['myvariable']='COMPLEX ARRAY';
}

Final step is to create tpl file in the directory you specified earlier. In this example, we have template name ‘user-login’. So, file name will be ‘user-login.tpl.php’. If you forget creating tpl file or misname it, drupal will fall back to use default way.

Further Question

Please leave your comment/question, if you have any concern implementing template file this way.

RESTFUL WCF Service


Download code sample

WCF has very good support for Representational State Transfer (REST) which is very popular since its introduction in 2000 by Ray Thomas Fielding in his PhD dissertation. REST builds on the client-server architecture where clients can make requests of services. There are lots of reasons to use REST. I am not going to describe them. Instead, in this article I will show you how to develop RESTFUL WCF service, host it in ASP.NET application (apparently IIS) and consume it.

Let’s Begin

For every WCF application, we need to have service contract that is an interface exposing. Make sure your project has reference to System.ServiceModel and System.ServiceModel.Web namespace.


[ServiceContract]
public interface IMService
{
 [OperationContract]
 [WebGet(UriTemplate = "Books", BodyStyle = WebMessageBodyStyle.WrappedRequest, ResponseFormat = WebMessageFormat.Json)]
 List GetBooks();

[OperationContract]
[WebInvoke(Method = "GET", UriTemplate = "Book/{id}", BodyStyle = WebMessageBodyStyle.WrappedRequest, ResponseFormat = WebMessageFormat.Json)]
BookModel GetBook(string id);

 [OperationContract]
 [WebInvoke(Method = "PUT", UriTemplate = "AddBook/{bookName}", BodyStyle = WebMessageBodyStyle.WrappedRequest, ResponseFormat = WebMessageFormat.Json)]
 string AddBook(string bookName);

 [OperationContract]
 [WebInvoke(Method = "POST", UriTemplate = "UpdateBook/{id}/{bookName}", BodyStyle =  WebMessageBodyStyle.WrappedRequest, ResponseFormat = WebMessageFormat.Json)]
 bool UpdateBook(string id, string bookName);

 [OperationContract]
 [WebInvoke(Method = "DELETE", UriTemplate = "DeleteBook/{id}", BodyStyle = WebMessageBodyStyle.WrappedRequest,  ResponseFormat = WebMessageFormat.Json)]
 bool DeleteBook(string id);
}

In above code, subtle difference is WebGetAttribute and WebInvokeAttribute. WebGetAttribute is for GET HTTP request while WebInvokeAttribute by default invokes POST HTTP request but it can be specified in Method to support other verbs like GET, PUT and DELETE. Inside both attributes there is UriTemplate which makes it possible to define URI for each resource by using specific template syntax. It is clear curly braces is being used for parameter. You can also specify the message format of the response. Default is xml. If we define the service implementing above interface, we can call http://localhost:port/Books to get the all books in json format. Easy, huh?

Configuration

To make the service RESTful we need to specify certain things on our service configuration. Yes, it is ABC of WCF. We need to define binding as “webHttpBinding” with webHttp behavior. Here is the service configuration, I used for this article.

<system.serviceModel>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true"
      multipleSiteBindingsEnabled="true" />
    <services>
      <service name="InetPrep.MathService.MService" behaviorConfiguration="">
        <endpoint address="" binding="webHttpBinding" behaviorConfiguration="restfulBehavior" contract="InetPrep.MathService.IMService">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8733/MService/" />
          </baseAddresses>
        </host>
      </service>
    </services>
    <behaviors>
      <endpointBehaviors>
        <behavior name="restfulBehavior">
          <webHttp />
        </behavior>
      </endpointBehaviors>
    </behaviors>
  </system.serviceModel>

For this sample, I have hosted my service in ASP.NET application. You need to add reference to the actual service implementation project if they are two different projects. All of the configuration will reside inside web.config file. To make the sample project more realistic, I am doing direct query to the database using Entity framework. Entire database script is in project if you want to import. To host the service in ASP.NET (IIS), we can add .svc file which hosts the service. There is very little code you need to worry about for this file.

<%@ ServiceHost Language="C#" Debug="true" Service="InetPrep.MathService.MService"%>

This file uses the configuration from the web.config file and hosts the service.

Service is Hosted now WHAT?

If you browse to http://localhost:40235/MathServiceHost.svc/Books, you will get json books data. Similarly, if you browse to http://localhost:40235/MathServiceHost.svc/Book/2, you will get information about a book with id 2. Useful, right? Now let’s try to add new book http://localhost:40235/MathServiceHost.svc/AddBook/newbook, you will get ‘Endpoint not found’. Similar message will be displayed, if you try to update and delete book. So, why is that? This is because whenever you type and browse url from your browser, it will be treated as GET request and there is not any matching operation we defined. To perform those operations you need to do that in different ways; 1. You can create HTML form and perform operation. 2. You can programmatically create requests and perform operation. Or 3. You can use Fiddler to create request and perform operation. I have created sample client project which allows you to add book. If you see in code-behind you can see code to create PUT request. You can easily do this using jQuery from client side.

var httpWebRequest = (HttpWebRequest)WebRequest.Create("http://localhost:40235/MathServiceHost.svc/AddBook/" +    txtBookName.Text);
httpWebRequest.ContentType = "text/json";
httpWebRequest.Method = "PUT";
string responseText = "";
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
 //streamWriter.Write(txtBookName.Text);//any parameter
}
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
 responseText = streamReader.ReadToEnd();
 lblMessage.Text = responseText;
}

Summary

So this concludes the basic RESTful service. It utilizes the basic building block of WCF to create RESTful service and shows you to host it in ASP.NET application. Please, do not hesitate to post any questions related to this article.

PHP and Accessing MSSQL Server in Unix/Linux


Introduction

Microsoft provides a very good driver and documentation on how to connect and work with their MS SQL Server. Unfortunately, it only works on windows operating system. So for Linux/Unix, you need to find different approach to connect with. FreeTDS is there for you to rescue. It is free and works with both Linux and Unix.

Details

For this post, I am using Ubuntu 12. The first step is of course having proper working FreeTDS. So, for this you need to install several packages. In your terminal just execute the command:


apt-get install freetds-bin freetds-common tdsodbc odbcinst php5-odbc unixodbc

This command will install all necessary components to add ability to connect to remote MSSQL server.

Second step is to copy the odbcinst.ini file from /usr/share/tdsodbc (in some case /usr/share/doc/freetds-common/examples/odbcinst.ini) to /etc. Yes, you can use GUI to copy the file but just make sure you backup the existing odbcinst.ini file in /etc. If you want to do this by command line here you go:


mv /etc/odbcinst.ini /etc/odbcinst.ini.bak

cp /usr/share/tdsodbc/odbcinst.ini /etc/

Yes!!! You are done with the configuration step. Now it is the time of coding, real challenge.

As you have your TDS driver and odbc in your unix, you can create PDO connection object and execute query based on that connection. Here you go:

<?php

 try {

  //$con = new PDO('odbc:Driver=FreeTDS; Server=full_machinename_or_ip_address\(servername_if_any); Database=db_to_connect; UID=username;PWD=password;);
  $con = new PDO('odbc:Driver=FreeTDS; Server=remote_server\mssqlserver; Database=db_students; UID=db_user; PWD=password123;');
  // Now you have connection object. You can query on your db.
  // Example to execute ful SQL query
  $result = $con->query('SELECT Name FROM dbo.students');
  foreach ($result as $row) {
   print $row['Name'] . '<br />';
  }

  // Example to execute stored procedure
  $result = $con->query('EXEC dbo.GetAllStudents');
  foreach ($result as $row) {
   print 'Name: ' . $row['Name'] . ' Grade: ' + $row['Grade'] . '<br />';
  }
  $con = null;
 } catch (PDOException $e) {
  echo $e->getMessage();
 }

Yes for Remote local table above code will work fine but the above code will fail when there is Linked Server. This means MSSQL Server has linked database which is somewhere else and can be other database server like oracle. In this case your $result will be false. To ensure that your code doesn’t fail on such type of scenarios, you need to execute two commands before actual query. Here is the full code which will work for Linked Server.

<?php

try {

 $con = new PDO('odbc:Driver=FreeTDS; Server=remote_server\mssqlserver; Database=db_students; UID=db_user; PWD=password123;');

 // Make sure it won't fail for Linked Server
 $command = $con->prepare('SET ANSI_WARNINGS ON');
 $command->execute();
 $command = $con->prepare('SET ANSI_NULLS ON');
 $command->execute();

 // Now you have connection object. You can query on your db.
 // Example to execute ful SQL query
 $result = $con->query('SELECT Name FROM dbo.students');
 foreach ($result as $row) {
  print $row['Name'] . '<br />';
 }

 // Example to execute stored procedure
 $result = $con->query('EXEC dbo.GetAllStudents');
 foreach ($result as $row) {
  print 'Name: ' . $row['Name'] . ' Grade: ' + $row['Grade'] . '<br />';
 }

 $con = null;
} catch (PDOException $e) {
 echo $e->getMessage();
}
?>

Yes you are done now. You can connect to MSSQL Sever from non windows machine and from PHP. If you have any questions just let me know via comments.

Calling .NET functions from JavaScript


Download full code from here.

Introduction

Javascript/Jquery is the client side language and it runs on the browser. It is fast because it doesn’t depend on the server for the response. Nowadays, jQuery is being used in the web development very much. It is fast and can really creates a cool and attractive web site. Jquery has a functionality to call the web service ($.ajax()). In this method we call the web service which is running on some server and this method gets the response which can be used as the developer wants to do. One important thing in ASP.NET is if you need to call the .NET function and you are not using that function in other pages, then it is not justifiable to create a web service and call the function. ASP.NET provides you a cool mechanism to utilize your server side function from your client side without officially creating the web service.

PageMethods and WebMethod attribute

Every method that you want to call from the client side code must be public and static .NET function and as web service method it must have System.Web.Services.WebMethod attribute. Then in your aspx page you can call your .NET function using PageMethods.MethodName. And you need to have ScriptManager control in your page with EnablePageMethods true.

WebMethodCall.aspx.cs

        [System.Web.Services.WebMethod]
        public static string GetName(string name)
        {
            return "Hello <strong>" + name + "</strong>";
        }

For example we have a GetName method in our code behind. So for this method to enable to call from client code, we need to add WebMethod attribute on it.

And its corresponding aspx page will have following javascript code to call the .NET function and display it in a div.

WebMethodCall.aspx


<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePageMethods="true">

</asp:ScriptManager>

<div>

<script language="javascript" type="text/javascript">

function Clicked() {

//PageMethods.set_path('WebMethodCall.aspx');

PageMethods.GetName('Pradip', Success, Failure);

}

function Success(result, userContext, methodName) {

$('#content').html(result);

}

function Failure(error, userContext, methodName) {

$('#content').text(error.get_message());

}

</script>

</div>

<a onclick="Clicked()" href="#">GetName call</a>

<br/>

<br/>

<div id="content" style="background-color: #B0B0B0; width: 500px; height: 500px;">

</div>

The code above is straightforward. In above code we called the .NET function ‘GetName’ using PageMethods.GetName which has three parameters: name parameter, success callback function and failure callback function. On Success we get the result object (in our case string) which is displayed as html in content div.

Even though the code above is very simple, you can call a complex database call and calculation from your client code. You just need to extend your server side function.

Download full code from here.

Issue when using with URL Routing

When you use the URL routing, the method of calling .NET function from javascript that I described above will not work as expected because if you look into the page source you can see the form action to ‘HomePage’ and when you debug javascript you can see service path as ‘HomePage’. So, for this we need to do some correction on this path. We need to call PageMethods.set_path(url) method to set the service path. You can just uncomment the code inside the Clicked() function. Now, you can see our code works for both ASPX page and page using URL routing.

Conclusion

Even web service is used very much while it is required to call .NET functions from client side code (Javascript/JQuery), when the function is used just in one page and it is not justifiable to build web service as it costs performance and separate service, it is good to use this method when you need to call .NET functions from client code.

Dynamic Pages with ASP.NET


Download complete code from here.

Introduction

If you are familiar with the SharePoint technologies you might have known that you can edit the appearance of certain portion of the page. Moreover in publishing page you can add and delete as many parts in the page as you like.

 Fig: Showing Edit enabled Page

Now a day web page is not just a static page which just shows the static information to the user. It would be more flexible to give the user to customize the view they want so that they can move the parts around the page, hide the parts and modify the property of parts. Adding such functionality is expensive and requires lot of works of developer and of course more error prone.

In this article I will give you the general overview of using web part manager and web part zone.

Introducing WebPartManager

WebPartManager control is an ASP.NET server control introduced from .NET 2.0. There is not any visual effect of this control in the page. But wait. This control can add items to and delete items from each zone of the page. This means there is no meaning for a page to contain only WebPartManager. There should be at least one WebPartZone. WebPartManager is page dependent control and it manages on that particular page. However you can add it in you master page if you require.

After adding the WebPartManager control into the webpage, now it is a time to create a Zone in that page. You can any techniques to create several zones in your page. This is directly dependent on your business logic. For this article I am using Table to create zone. I am creating four zones.

Note that you can drag and drop the control from toolbox into your page or you can write a code.


<asp:WebPartManager ID="WebPartManagerDefault" runat="server">

</asp:WebPartManager>

<table style="width: 100%;">

<tr>

<td colspan="4">

&nbsp;

<asp:WebPartZone ID="WebPartZoneTop" runat="server">

<ZoneTemplate>

</ZoneTemplate>

</asp:WebPartZone>

</td>

</tr>

<tr>

<td>

&nbsp;

<asp:WebPartZone ID="WebPartZoneLeft" runat="server">

<ZoneTemplate>

</ZoneTemplate>

</asp:WebPartZone>

</td>

<td style="width: 50%;">

&nbsp;

<asp:WebPartZone ID="WebPartZoneCenter" runat="server">

<ZoneTemplate>

</ZoneTemplate>

</asp:WebPartZone>

</td>

<td>

&nbsp;

<asp:WebPartZone ID="WebPartZoneRight" runat="server">

</asp:WebPartZone>

</td>

<td>

&nbsp;

</td>

</tr>

</table>

Now you have added the WebPartZone in your page. Inside WebPartZone you can add almost anything that can be added in your web form. You can add HTML elements, User controls, and Web parts and so on.

Let’s add two asp controls; image control and calendar control in the page. Now, your code looks like this


<asp:WebPartManager ID="WebPartManagerDefault" runat="server">

</asp:WebPartManager>

<table style="width: 100%;">

<tr>

<td colspan="4">

&nbsp;

<asp:WebPartZone ID="WebPartZoneTop" runat="server">

<ZoneTemplate>

<asp:Image ID="ImageBanner" runat="server" ImageUrl="~/Images/Banner.png" Title="Image Control" />

</ZoneTemplate>

</asp:WebPartZone>

</td>

</tr>

<tr>

<td>

&nbsp;

<asp:WebPartZone ID="WebPartZoneLeft" runat="server">

<ZoneTemplate>

<asp:Calendar ID="CalendarDefault" runat="server" Title="Calendar Control"></asp:Calendar>

</ZoneTemplate>

</asp:WebPartZone>

</td>

<td style="width: 50%;">

&nbsp;

<asp:WebPartZone ID="WebPartZoneCenter" runat="server">

<ZoneTemplate>

</ZoneTemplate>

</asp:WebPartZone>

</td>

<td>

&nbsp;

<asp:WebPartZone ID="WebPartZoneRight" runat="server">

</asp:WebPartZone>

</td>

<td>

&nbsp;

</td>

</tr>

</table>

If you run the project now you will get the output like this

 

                Fig: output 1

You can see the title of each control. They are taking title from the ‘Title’ attribute of control. Even the control doesn’t contain this property by default you can add it so that you can have meaningful title displayed rather than default ‘untitled’. Note that you can customize the control. You can minimize it, restore it or you can close it. If you make some changes for example minimize the asp image control and reopen the page you can see your image control in minimize state. GREAT!!!

Now let try one more thing, let’s close the image control. Now, you can see it is nowhere in the page. Even if you reopen your page there will not be any image control.

Note that the customization information is saved in App_Data folder in ASPNETDB database.

Introducing different mode of the page

Now I will give you the description of different mode of the page.  User can add, move or change the page they are in by changing the page mode. For now let’s add the DropDownList in the page and make certain change in the code behind.


<tr>

<td colspan="4" align="right">

<asp:DropDownList ID="DropDownList1" runat="server" AutoPostBack="True"

onselectedindexchanged="DropDownList1_SelectedIndexChanged">

</asp:DropDownList>

&nbsp;&nbsp;&nbsp;

</td>

</tr>

Changes in code-behind.


protected void Page_Init(object sender, EventArgs e)

{

foreach (WebPartDisplayMode wpMode in WebPartManagerDefault.SupportedDisplayModes)

{

string modeName = wpMode.Name;

ListItem listItem = new ListItem(modeName, modeName);

DropDownList1.Items.Add(listItem);

}

}

protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)

{

WebPartDisplayMode displayMode = WebPartManagerDefault.SupportedDisplayModes[DropDownList1.SelectedValue];

WebPartManagerDefault.DisplayMode = displayMode;

}

Open the page. You will see two drop down items. One is browse and one is design. If you change the mode to design mode you can move your web part from one web part zone to another.

But still where is my closed web part?

In this section I will show you to add two additional modes of page. One is catalog mode in which you can see your closed web part and you can add web part to any zone. Another is edit mode in which you can edit the property of your web part including display. If you have created your custom web part you can make the property editable when you are in edit mode. (I will show you how to do this on another article.)

For now let’s add the following piece of design code in your working page.


<asp:CatalogZone ID="CatalogZoneMain" runat="server">

<ZoneTemplate>

<asp:PageCatalogPart ID="PageCatalogPartMain" runat="server" />

<asp:DeclarativeCatalogPart ID="DeclarativeCatalogPartMain" runat="server">

<WebPartsTemplate>

<asp:TextBox ID="TextBox" runat="server" Title="Text Box"></asp:TextBox>

</WebPartsTemplate>

</asp:DeclarativeCatalogPart>

</ZoneTemplate>

</asp:CatalogZone>

<asp:EditorZone ID="EditorZoneMain" runat="server">

<ZoneTemplate>

<asp:AppearanceEditorPart ID="AppearanceEditorPartMain" runat="server" />

<asp:BehaviorEditorPart ID="BehaviorEditorPartMain" runat="server" />

<asp:LayoutEditorPart ID="LayouteEditorPartMain" runat="server" />

<asp:PropertyGridEditorPart ID="PropertyGridEditorPartMain" runat="server" />

</ZoneTemplate>

</asp:EditorZone>

Now you can see two additional page modes in your drop down menu. If you select catalog mode you can see your closed web part. You can add this web part in your page. Moreover, if you click on Declarative Catalog link you will get another the list of web part (in this case only one, textbox control). You can add this web part to any web part zone.

If you select edit mode you can now edit the property of web part like Appearance and Behavior. Generally, normal user shouldn’t see this option. There are more than those properties for editing which is still invisible. To view those properties you need to change your web.config file. Add following configuration in System.web.


<webParts>

<personalization>

<authorization>

<allow users="*" verbs="enterSharedScope" />

</authorization>

</personalization>

</webParts>

And add following piece of code in Page_Load


if (WebPartManagerDefault.Personalization.Scope == PersonalizationScope.User

&& WebPartManagerDefault.Personalization.CanEnterSharedScope)

{

WebPartManagerDefault.Personalization.ToggleScope();

}

When you change the mode to edit and chose edit for any web part or control, you should be able to see something like this.

Fig: Web part in edit mode.

Modifying Zone property and Verbs in Web Part

There are many properties those are used to assure certain behavior of web part zone. For example if you don’t want to change the web part of certain zone, then you can use the AllowLayoutChange property. You can use LayoutOrientation property to make sure you add web part in either horizontal or vertical orientation.

Verbs are property of web part which enable/disable the corresponding feature in the web part. The available verbs are CloseVerb, ConnectVerb, DeleteVerb, EditVerb, ExportVerb, HelpVerb, MinimizeVerb and RestoreVerb. They all have their own meaning. For example if you use following code in your page then you will not able to edit your web part. The corresponding menu will be disabled.

</pre>
<asp:WebPartZone ID="WebPartZoneTop" runat="server">

<EditVerb Enabled="false" />

<ZoneTemplate>

<asp:Image ID="ImageBanner" runat="server" ImageUrl="~/Images/Banner.png" Title="Image Control" />

</ZoneTemplate>

</asp:WebPartZone>
<pre>

Fig: Disabled edit option

Conclusion

There are plenty of other stuffs that are part of web part. I will show you them on another articles step by step. Web part is very vast and powerful section in ASP.NET. Web part helps developers to make dynamic and modular pages. I will show you to create your own custom web part in another article.

Dining Philosopher Problem and AutoResetEvent.


Introduction

Full code can be downloaded from here.

I think we all know the famous classic problem of dining philosopher. In this problem, we consider n philosophers sitting in round table and n forks and all of them want to eat the spaghetti in front of each one. To eat spaghetti, philosopher must have two forks. The problem is philosopher 1 is taking one fork and waiting philosopher2 for second fork. Similarly, philosopher 2 is taking a fork and waiting philosopher3 for a fork. And philosopher n is taking a fork and waiting philosoper1 for a fork. So, what is actually happening is each philosopher cannot get the two forks at a time because each philosopher is taking a fork and waiting. So, here is the DEADLOCK.

For 5 philosophers we can assume the figure


Fig: Dining Philosopher Problem

Similar incident can be happens in our program and operating system where many processes are struggling to get the resources. There are certain criteria which must meet to cause the deadlock. They are:

1. Each resource can be used by only one thread or process.
2. Thread/Process is holding a resource and waiting for other resource to continue.
3. Resources those are granted previously cannot be forcibly taken away.
4. There must be chain of threads/processes (more than two); each is waiting for the resource held by next
thread/process.

To avoid deadlock, we can negate any of the above conditions. For dining philosopher problem, we will negate the second condition to avoid deadlock.

Code
Full code can be downloaded from here.
I have used AutoResetEvent to implement the dining philosopher problem. I have used one AutoResetEvent as mutex and n others as philosopher events.
There are three states of philosopher.

    enum State
    {
        Thinking,
        Eating,
        Hungry
    }

Let’s look at the code:

private void TakeForks(int i)
        {
            _mutex.WaitOne();
            _philosophersState[i] = State.Hungry;
            TryGetForks(i);
            _mutex.Set();
            _philosopherEvents[i].WaitOne();
        }

        private void TryGetForks(int i)
        {
            if (_philosophersState[i] == State.Hungry &&
                _philosophersState[right(i)] != State.Eating &&
                _philosophersState[left(i)] != State.Eating)
            {
                _philosophersState[i] = State.Eating;
                _philosopherEvents[i].Set();
            }
        }

        private void PutForks(int i)
        {
            _mutex.WaitOne();
            _philosophersState[i] = State.Thinking;
            TryGetForks(right(i));
            TryGetForks(left(i));
            _mutex.Set();
        }

First of all philosopher tries to take both fork. If it is not possible, it waits for the signal from its left and right. Whenever it gets the signal, philosopher again tries to acquire both forks and same process repeats.

void checkForConflict(int i)
        {
            if (_philosophersState[left(i)] == State.Eating)
                Console.WriteLine("Conflict between " + left(i) + " and " + i);
            if (_philosophersState[right(i)] == State.Eating)
                Console.WriteLine("Conflict between " + i + " and " + right(i));
        }

Above code checks for the conflict and displays conflict message whenever two philosophers try to eat using same resource. Our program mustn’t print the conflict messages.

Conclusion
Dining philosopher is a classic deadlock problem of operating system. Every deadlock can be avoided by negating any of the four essential conditions of deadlock.

I have used AutoResetEvent as mutex and for signalling purpose. However, we can use others also.