Monthly Archives: February 2012

Asp.Net MVC 3.0 with dependency injection using Ninject container.

I did not use the famous jargon “Inversion Of Control IOC” intentionally here so that developers who are taking a shot at implementing(or understanding the existing application) dependency injection in their MVC application are not puzzled by the debate over comparing/relating IOC  with DI.

For now, let’s settle on that   “IOC is an architecture principle and DI is configurable piece of code which follows IOC.”

I am going to cover the much needed  WHY,WHERE and HOW of DI

WHY to use DI: Even though MVC represents Separation of Concerns quite strongly, yet controllers are tightly coupled to Data access model/service.

// using Entity framework here.
private NorthwindEntities _Db = new NorthwindEntities();
public ActionResult CustomerList()
 {
 var model = _Db.Customers.ToList();
 return View(model);
 }

In the above code, we have NorthwindEntities entity framework context used for Data access. let’s say we need to change the data access methodology for some reason (trust me it happens more often than you assume), then we need to change controller codes all across the application.  So, why not creating a way where controller can become loosely coupled with data access methodology.

Hence here are few situations when to use IOC – DI

  1. When we need our components to be loosely coupled.
  2. When Unit testing is important and database may not be ready in the beginning. Test Driven Development TDD.
So, rather than instantiating the database context object we should pass an interface to the controller. This reduces extra work to create a test/mock data for testing. Even the database is not ready we can test our action methods easily as all  controller needs is an Interface.
WHERE to use DI:
  1. Initialization of controllers should be changed. controller’s constructor should accept interface to a repository (ICustomerRepository).
  2. In Global.asax and under Application_Start event setup the binding to interface.
 HOW to use:  piece of code to implement.
Interface and Repository classes
</pre>
</div>
<div>
public interface ICustomerRepository
 {
List<Customer> GetAll();
 }

// entity framework data access

public class CustomerEFRepository : ICustomerRepository
 {
 #region ICustomerRepository Members

public List<MVC_IOC_DI.EF.Customer> GetAll()
 {
 NorthwindEntities _db = new NorthwindEntities();
 return _db.Customers.ToList();
 }

#endregion
 }

// Sql to Linq data access

public class CustomerLinqRepository : ICustomerRepository
 {
 #region ICustomerRepository Members

public List<Customer> GetAll()
 {
 NorthwindLinqDataContext _db = new NorthwindLinqDataContext();
 return _db.Customers.ToList();
 }

#endregion
 }

// Home Controller

public class HomeController : Controller
 {
 private readonly ICustomerRepository irepository;

public HomeController(ICustomerRepository repository )
 {
 irepository = repository ;
 }

// right click on this method and Add View (as List template) strongly typed to Customer object.
public ActionResult CustomerList()
 {
 var model = irepository.GetAll() ;
 return View(model);
 }

}</div>
<div>
Ninject IOC container related code:  You can download Ninject libraries for MVC3.0 from http://nuget.org/packages/Ninject.MVC3 . If you are using VS2010 just go to NuGet Package manager and search for Ninject and install it (Nuget really rocks :))
</div></div>
<div>
<pre><div>
using Ninject;
using Ninject.Syntax;</div>
<div></div>
<div>//You would need a dependency resolver class to instruct MVC about the binding/mapping you need to specify in //global.asax.</div>
<div>

public class NinjectDependencyResolver : IDependencyResolver
 {
 private readonly IResolutionRoot _resolutionRoot;

public NinjectDependencyResolver(IResolutionRoot kernel)
 {
 _resolutionRoot = kernel;
 }

public object GetService(Type serviceType)
 {
 return _resolutionRoot.TryGet(serviceType );
 }

public IEnumerable<object> GetServices(Type serviceType)
 {
 return _resolutionRoot.GetAll(serviceType);
 }

}

</div>
<pre>// call this method ins Application_Start event</pre>
private void SetupDependencyInjection()
 {
 // create Ninject DI kernel
 IKernel kernel = new StandardKernel();

// register repository with specific data access repository DI container
 kernel.Bind<ICustomerRepository>().To<CustomerLinqRepository>();
// Later you may change it to EF data access easily.
//kernel.Bind<ICustomerRepository>().To<CustomerEFRepository>();
// Tell mvc to use our DI Ninject container
 DependencyResolver.SetResolver(new NinjectDependencyResolver(kernel));
 }
<pre>

Here is the summary of the whole implementation.

  1. Include Ninject libraries in your application.
  2. Write Interface for each entity repository. — ICustomerRepository
  3. Write repository classes which implements the interface. — CustomerEFRepository or CustomerLinqRepository
  4. Controller should have interface as a class variable.
  5. Write a constructor for the controller which accepts this interface as parameter.
  6. Write a dependency resolver class for Ninject container. Which will change the dafualt way of how the MVC  resolves the dependency.
  7. Map the bindings in Application_Start event of Global.asax.cs.
These steps are for a very basic implementation of DI in MVC 3. 

For a beginner, it is a good start. Once the skeleton is ready, it’s easy to put on some fat :).

I hope it is useful.


Advertisements

Jquery tabs – maintaining selected tab during postback

I am sure Jquery tabs made everyone think twice before he opts for Ajaxtoolkit tabcontainers. I thought the same before implementing it in a .Net 2.0 web application.  Only issue i faced was that after each postback selected tab index is set to default.  So i had to find a work around which can be very handy at times.

.aspx code:


<!-- this field stores tab index -->

<asp:HiddenField runat="server" ID="selectedTab" />

<div id="myTabs" style="width: 500px;">
 <ul>
 <li><a href="#tab-1">Tabs</a></li>
 <li><a href="#tab-2">AutoComplete</a></li>
 </ul>
 <div id="tab-1">
 <asp:Button runat="server" ID="btnTest" Text="Do PostBack" OnClick="btnTest_Click" />
 </div>
 <div id="tab-2">

 </div>
 <asp:Button runat="server" ID="btnPostBack" Text="Do PostBack2" OnClick="btnPostBack_Click" />
 </div>
 </div>

jquery script:


<script type="text/javascript">
 $(document).ready(function () {

// <!-- Tabs script -->

var indx = $('#' + '<%= selectedTab.ClientID %>').val();

if (indx == '') {
 $("#myTabs").tabs({ selected: 0 });
 $('#' + '<%= selectedTab.ClientID %>').val('0');
 }
 else {
 $("#myTabs").tabs({ selected: indx });
 $('#' + '<%= selectedTab.ClientID %>').val(indx);
 }

$("#myTabs").tabs({
 select: function (event, ui) {
 $('#' + '<%= selectedTab.ClientID %>').val(ui.index);
 }
 });
 // tabs script ends

});

</script>

I am storing tab index in a hidden variable  and after every post back restore it. It is being handled by Select event of jquery Tabs API.  for more info please refer to the documentation at jquery site. http://docs.jquery.com/UI/Tabs#events 

I hope it is useful.

Selecting a dropdownlist by text using Jquery filter() API

It is a small issue i came across recently.  I was using a dropdownlist in asp.Net mvc which was populated using $.ajax call. I need to select the item in dropdownlist if  it’s text is “SearchText”.

It seems simple using Contains  API from Jquery. but if the text is not available in the data source it throws javascript exception when we try to select the item.

There is an easy way of doing the check and selecting the text in dropdownlist.

.Filter() – Jquery API


$('#MyList option').filter(function() {

return ($(this).text() == searchText);

}).attr('selected', 'selected');

Here, For each item the text will be compared and returned true only when an exact match is found. if  searchText is empty also it will not throw any exception while setting the attribute.

Code really seems very easy and handy. This anonymous method syntax is nothing new to C# developers.

I hope its useful!

Jquery Modal dialog as Confirm in Asp.Net webforms

I love Jquery! it made me friends with client side scripting. Earlier it used to haunt me all the time.

If we have a button on a webform which should confirm the user action on click like a Delete button Jquery provides
Javascript methods:

<script type="text/javascript">
 $(document).ready(function () {
// this method opens a div with id="dialogContent" as a modal dialog box with Yes and No buttons.

$('#dialogContent').dialog({

autoOpen: false,
modal: true,
 bgiframe: true,
 title: "Confirm your action",
 width:200,
 height: 200
 });

});

// this method is called when Delete button is clicked.
function rowAction(uniqueName) {

$('#dialogContent').dialog('option', 'buttons',
 {
 "Yes": function () {
 __doPostBack(uniqueName, '');
 $(this).dialog("close");
 },
 "No": function () { $(this).dialog("close"); }
 });

$('#dialogContent').dialog('open');

return false;
 }
 </script>

.aspx code:


<asp:Button ID="btnDelete" runat="server" CommandArgument='<%# Eval("ProductID") %>'
Text="Edit" OnClick="btnDelete_Click" OnClientClick="javascript:return rowAction(this.name);" />

<div id="dialogContent">
Are you sure?

</div>

Code behind :


protected void Page_Load(object sender, EventArgs e)
 {

// register the postback reference. specify the control we are forcing to postback.

ClientScript.GetPostBackEventReference(btnDelete, string.Empty);
 }

// this event is fired when user presses <strong>Yes</strong> from Confirm Modal dialog.

protected void btnDelete_Click(object sender, EventArgs e)
 {
Button b = sender as Button;
if (b != null)
{
// do your actions here
}
 }

This way we get Jquery modal confirm box on a button click. once you press Yes we use our old friend javascript method __doPostBack(controlName, ”) to continue server side execution.

Please note that in __doPostback method second parameter is empty string,  If you need to pass some arguments while enforcing a postback. convert it to a Json string and pass it to code behind. You can convert this json string to C# object using Javascript serializer. 
Please refer to my article on json string to C# coversion http://wp.me/p1hH3Q-2E

I hope it is useful!

Converting a Json string to C# object using JavaScriptSerializer

Gradually web development is shifting it’s focus to Client side programming day by day. Json is simply a Fat Free alternative to XML. Earlier XML was our commonly accepted data format across all the platforms, but JSON seems to be even more promising because of it’s light weight and familiar syntax (reminds me of .Net  object initializer).   Jquery on the other hand has become a standard which has excellent support with JSON format.

Let’s say we have a C# class Product.


class Product {

int ProductID;

string ProductName;

int CategoryID;

int SupplierID;

decimal UnitPrice;

}

JSON string example : We need to make sure our json string syntax is correct.  Class property names should be same to map it by default.

Here is the syntax

“{Property1 : ‘stringvalue’ , Property2 : ‘stringValue2’, Property3 : 123 }”

var jsonProductString = "{ ProductID :" + pid + ", ProductName :'" + pName + "',CategoryID :" + categoryId + ", SupplierID :" + supplierId + ", UnitPrice :" + unitPrice + "}";

Conversion to C# object: this is code is tested in .Net4.0.


System.Web.Script.Serialization.JavaScriptSerializer serializer = new System.Web.Script.Serialization.JavaScriptSerializer();

 var p = serializer.Deserialize<Product>(args);
// p is Product object initialized with Json string values.

Interesting part is after deserialization all the data types are easily mapped to Product class data types

Update:  There is a new serialization technique which performs even better for Json serialization. It is Json.Net library developed by James Newton King. it is available on codeplex.

Read more about Json.Net library on my Post on Json.Net library.
I hope it will be useful!!