Posts for the tag: Unity

Feb
24
2010

Build a REST Web Application with WCF and jQuery

Introduction

So at my work, we started on a new web application, and mainly because a lot of guys working on it were going to be new and also because it is somewhat a visible project; we figured we would keep the risk low and use the traditional web forms ASP.Net application.

On the other hand we still wanted the separation of concerns you get from a MVC style application, and because we were also planming on using designers for the web pages who were very proficient with jQuery but who did not know much about ASP.net. As a matter of fact, most of these guys write jQuery and HTML with a simple text editor…show offs :)

Also, for performance reasons and the fact the web designers were very familiar with the protocol, we wanted to pass JSON objects back and forth from the client to the server and vice versa.

Another goal is we want to keep as little as code as possible in the web project and place it in a different “Core” assembly. This would make deployments for us easier.

The Solution Layout

The solution looks like this:

The EventList.aspx page will be the page I will use for this demo. I deleted the associated code-behind files with and also removed the references of the code-behind from the page deplaration.

When I added the EventService.svc WCF Service into the project, Visual Studio added the EventService.svc.cs file and the IEventService service contract interface. I moved them to the Core project and changed the namespaces.

I also added a folder for the Unity service factory build up. You can see how I did it in a previous post.

The Service

Since I moved the associated files that were added when I added the WCF Service, I have to go in and change the declarations so they point to the proper place.

   1: <%@ ServiceHost 
   2:     Language="C#" 
   3:     Debug="true" 
   4:     Service="RestSample.Core.ServiceContracts.EventsService" 
   5:     Factory="RestSample.Core.ServiceContrainer.UnityServiceHostFactory" 
   6: %>

 

Also the code behind reference was moved and Factory attribute was added to point to my custom Unity Service Host Factory.

The Service Contract

The Service contract needs to be decorated with the ServiceContract attrubute; but I also need to specify that this message will take “POST” requests, and that the protocal will be JSON.

   1: using System.ServiceModel;
   2: using System.ServiceModel.Web;
   3: using RestSample.Core.DataContracts;
   4:  
   5: namespace RestSample.Core.ServiceContracts
   6: {
   7:     [ServiceContract]
   8:     public interface IEventsService
   9:     {
  10:         [OperationContract]
  11:         [WebInvoke(Method = "POST",
  12:             ResponseFormat = WebMessageFormat.Json,
  13:             BodyStyle = WebMessageBodyStyle.Bare)]
  14:         EventList GetLatestEvents();
  15:     }
  16: }

 

The implantation of this contract is injected with my controller where my response will be built up.

Here is the service contract implementation:

   1: using RestSample.Core.Controllers;
   2: using RestSample.Core.DataContracts;
   3:  
   4: namespace RestSample.Core.ServiceContracts
   5: {
   6:     public class EventsService : IEventsService
   7:     {
   8:         private readonly IEventController _eventController;
   9:  
  10:         public EventsService(IEventController eventController)
  11:         {
  12:             _eventController = eventController;
  13:         }
  14:  
  15:         #region IEventsService Members
  16:  
  17:         public EventList GetLatestEvents()
  18:         {
  19:             return _eventController.GetLatestEvents();
  20:         }
  21:  
  22:         #endregion
  23:     }
  24: }

 

Here is the controller class implementation:

   1: using System;
   2: using System.Collections.Generic;
   3: using RestSample.Core.DataContracts;
   4:  
   5: namespace RestSample.Core.Controllers
   6: {
   7:     public class EventController : IEventController
   8:     {
   9:         #region IEventController Members
  10:  
  11:         public EventList GetLatestEvents()
  12:         {
  13:             var list = new EventList {Items = new List<EventItem>()};
  14:             const int upper = 5;
  15:             for (int i = 0; i < upper; i++)
  16:             {
  17:                 list.Items.Add(new EventItem
  18:                                    {
  19:                                        EventCode = i.ToString(),
  20:                                        EventDate = DateTime.Today.AddDays(-1*i).ToLongDateString(),
  21:                                        EventName = string.Format("Name {0}", i)
  22:                                    });
  23:             }
  24:  
  25:             return list;
  26:         }
  27:  
  28:         #endregion
  29:     }
  30: }

Obviously I am just returning back trash, but you get the point. Here are the data contracts:

   1: using System.Runtime.Serialization;
   2:  
   3: namespace RestSample.Core.DataContracts
   4: {
   5:     [DataContract]
   6:     public class EventItem
   7:     {
   8:         [DataMember]
   9:         public string EventCode { get; set; }
  10:         [DataMember]
  11:         public string EventName { get; set; }
  12:         [DataMember]
  13:         public string EventDate { get; set; }
  14:     }
  15: }

 

   1: using System.Collections.Generic;
   2: using System.Runtime.Serialization;
   3:  
   4: namespace RestSample.Core.DataContracts
   5: {
   6:     [DataContract]
   7:     public class EventList
   8:     {
   9:         [DataMember]
  10:         public IList<EventItem> Items { get; set; }
  11:     }
  12: }

 

The web.config Set Up.

Because I want to return JSON, and because I moved the service files; I need to make some changes to the System.ServiceModel section of the web.config.

   1: <system.serviceModel>
   2:     <behaviors>
   3:         <serviceBehaviors>
   4:             <behavior name="RestSample.Core.ServiceContracts.EventsServiceBehavior">
   5:                 <serviceMetadata httpGetEnabled="true"/>
   6:                 <serviceDebug includeExceptionDetailInFaults="false"/>
   7:             </behavior>
   8:         </serviceBehaviors>
   9:   <endpointBehaviors>
  10:     <behavior name="WebHttpBehavior">
  11:       <webHttp />
  12:     </behavior>
  13:   </endpointBehaviors>
  14:     </behaviors>
  15:     <services>
  16:         <service behaviorConfiguration="RestSample.Core.ServiceContracts.EventsServiceBehavior" name="RestSample.Core.ServiceContracts.EventsService">
  17:             <endpoint address="" binding="webHttpBinding" contract="RestSample.Core.ServiceContracts.IEventsService" behaviorConfiguration="WebHttpBehavior">
  18:                 <identity>
  19:                     <dns value="localhost"/>
  20:                 </identity>
  21:             </endpoint>
  22:             <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
  23:         </service>
  24:     </services>
  25: </system.serviceModel>

I added an Endpoint Behavior and specified webHttp and then referenced it in the endpoint. This enables the “web programming model” for WCF which makes the service RESTful.

I also changed the name and contract location of the service so it points to new location in my solution.

Now my service is ready and if I run the service file at this point I get the standard service page to come up to show the everything is configured properly.

The Client

Now that the service is working I am just going to write some jQuery to make a call to the service when a button is click.

Here is the aspx page.

   1: <%@ Page Title="" Language="C#" MasterPageFile="~/Shared/Main.Master" %>
   2: <asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
   3:     <script src="../Scripts/json2.js" type="text/javascript"></script>
   4:     <script src="../Scripts/restsample.js" type="text/javascript"></script>
   5: </asp:Content>
   6: <asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
   7:     
   8:     <input type="button" value="Make Call" id="restCall" />
   9: </asp:Content>

Here is the jQuery

   1:  
   2: $(document).ready(function() {
   3:     setInputFunction();
   4: });
   5:  
   6: function setInputFunction() {
   7:     $('input').click(function() {
   8:         makeEventCall();
   9:     });
  10: }
  11:  
  12: function makeEventCall() {
  13:     $.ajax({
  14:         url: 'http://localhost:56296/Services/EventsService.svc/GetLatestEvents',
  15:         type: "POST",
  16:         processData: false,
  17:         contentType: "application/json",
  18:         timeout: 10000,
  19:         dataType: "text",  // not "json" we'll parse
  20:         success: function(data) {
  21:             loadSuccessful(data);
  22:         }
  23:     });
  24: }
  25:  
  26: function loadSuccessful(data) {
  27:     var result = JSON.parse(data);
  28:     console.log('result', result);
  29: }
  30:  
  31:  

So the jQuery code above makes a call to the service when the button is clicked. Here are some things to notice about this jQuery code.

  • First off, you cannot see it here but I have a script reference to the jQuery 1.4.1 file located on the Microsoft CDN. More on that here.
  • The url is the a combination of the service url and the function GetLatestEvents.
  • I need to specify “POST” as the type because that is what I specified on my ServiceContract.
  • I am going to return back text and then parse it using Douglas Crockford's json2.js.
  • For this demo, I am just going to log the response to the Firebug console using the console.log feature. (Note: remember to take this out later because you will get a JavaScript error in other browsers).

So with I am done and now when I bring up that web page and click the button I get this JSON response back.

{"Items":[{"EventCode":"0","EventDate":"Saturday, February 20, 2010","EventName":"Name 0"},
{"EventCode":"1","EventDate":"Friday, February 19, 2010","EventName":"Name 1"},
{"EventCode":"2","EventDate":"Thursday, February 18, 2010","EventName":"Name 2"},
{"EventCode":"3","EventDate":"Wednesday, February 17, 2010","EventName":"Name 3"},
{"EventCode":"4","EventDate":"Tuesday, February 16, 2010","EventName":"Name 4"}]}

The response in Firebug looks like this:

response

 

Hope that helps :)

Jan
24
2009

Creating a Web Application Using MVC, Unity and NHibernate – Part 2 nHibernate

Introduction

In the last post I set up NHibernate and created a simple test to retrieve one record from the database.  Now I would like to join the News table and Author table together and then create a test to see if I can successfully retrieve a record that contains both data from both tables joined together.

If you recall my schema looks like this:

 

 

 

 

So the first thing I would like to do is change create the mapping and DTO class for the Author table, but before I can do that, I need to add a reference of the Iesi.Collections.dll external assembly to my projects so I can create the ISet<> collection object.  Since one author can have many news items, my author class will have a collection of news items.  Since each of these news items must be unique, the ISet collection object will not allow you to add duplicate news items.

The Author Mapping File and Class

The Author mapping file will be set up just like the News mapping file:

    1 <?xml version="1.0" encoding="utf-8" ?>

    2 <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="News.Core" namespace="News.Core.Dto">

    3   <class name="News.Core.Dto.AuthorDto, News.Core" table="Author">

    4     <id column="AuthorId" name="AuthorId" type="long" unsaved-value="0">

    5       <generator class="native"></generator>

    6     </id>

    7     <property column="UserName" name="UserName" type="string" not-null="true"/>

    8     <property column="FirstName" name="FirstName" type="string" not-null="true"/>

    9     <property column="LastName" name="LastName" type="string" not-null="true"/>

   10     <property column="Password" name="Password" type="string" not-null="true"/>

   11     <property column="EmailAddress" name="EmailAddress" type="string" not-null="true"/>

   12     <property column="DateAdded" name ="DateAdded" type="DateTime" not-null="true" />

   13     <property column="DateUpdated" name ="DateUpdated" type="DateTime" not-null="true" />

   14     <property column="IsActive" name="IsActive" />

   15 

   16     <set name="NewsItems" table="News" generic="true" inverse="true">

   17       <key column="AuthorId" />

   18       <one-to-many class="News.Core.Dto.NewsItemDto, News.Core"/>

   19     </set>

   20   </class>

   21 </hibernate-mapping>

 

The first thing I need to is add the hibernate-mapping tag with xmlns namespace set so I can get the intellisense.  Next I add the Author class, specifying its namespace and assembly location, and just like the NewsItem class I start mapping the fields to the class properties.

As seen from the schema shown above, the Author table has a foreign key relationship in the News table, so I need to tell NHibernate about that relationship.  So to map the relationship, I have added a “set” tag.  The set tag tells NHibernate that the Author class has a collection of NewsItems and each of these news items are unique.  Now, if I wanted the Author class to have a collection of NewsItems that were not unique then I would use the bag tag, but in my case the set tag is what I want.

Here’s what’s going on:

·          The set attribute name is the child class that will be contained in the Author class.

·          The table attribute specifies the child table in the database that has the foreign key relationship.  In my case it is the News table.

·          Generic tells NHibernate that I want to use the ISet<T> collection  (Note:  This is a class that NHibernate provides is like the IList<T> class, but this class will not let you add a duplicate item to its collection.  I need to add a reference to the Iesi.Collections.dll assembly to use it.

·          Inverse tells NHibernate that I want the child class to control the relationship and not the parent.

·          The key column tells NHibernate what the foreign key field is in the child table.

·          And finally the one-to-many tag tells NHibernate what namespace and assembly the child class is in.

Woops!  Don't forget to make the mapping xml file an embedded resource.

Here is the class file.

    6     public class AuthorDto

    7     {

    8 

    9         public virtual long AuthorId { get; set; }

   10 

   11         public virtual string UserName { get; set; }

   12 

   13         public virtual string FirstName { get; set; }

   14 

   15         public virtual string LastName { get; set; }

   16 

   17         public virtual string Password { get; set; }

   18 

   19         public virtual string EmailAddress { get; set; }

   20 

   21         public virtual DateTime DateAdded { get; set;  }

   22 

   23         public virtual DateTime DateUpdated { get; set; }

   24 

   25         public virtual bool IsActive { get; set; }

   26 

   27         public virtual ISet<NewsItemDto> NewsItems { get; set; }

   28 

   29     }

 

Notice the ISet class?  Cool!

The News Mapping File and Class

The News class will slightly change.  Instead of holding the AuthorId field, the News class will be holding its parent Author class, so I will need to change the mapping file to reflect this also.

So here is the mapping file:

    1 <?xml version="1.0" encoding="utf-8" ?>

    2 <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Audubon.Core" namespace="Audubon.Core.Dto">

    3   <class name="Audubon.Core.Dto.NewsItemDto, Audubon.Core" table="News">

    4     <id column="NewsId" name="NewsId" type="long" unsaved-value="0">

    5       <generator class="native"></generator>

    6     </id>

    7     <many-to-one name="Author" column="AuthorId" not-null="true" class="Audubon.Core.Dto.AuthorDto, Audubon.Core" />

    8     <property column="DateAdded" name="DateAdded" type="DateTime" not-null="true"/>

    9     <property column="DateUpdated" name="DateUpdated" type="DateTime" not-null="true"/>

   10     <property column="DatePublished" name ="DatePublished" type="DateTime" not-null="true" />

   11     <property column="Title" name="Title" type="string" not-null="true"/>

   12     <property column="ShortDescription" name="ShortDescription" type="string" not-null="false"/>

   13     <property column="Body" name="Body" type="string" not-null="true"/>

   14     <property column="IsFrontPage" name="IsFrontPage"/>

   15     <property column="IsPublished" name="IsPublished"/>

   16 

   17   </class>

   18 </hibernate-mapping>

 

Notice I have changed the AuthorId property tag to a many-to-one tag which specified the Author class.

Here is the NewsItem class with the modification for Author property:

    5     public class NewsItemDto

    6     {

    7         public virtual long NewsId { get; set; }

    8 

    9         public virtual AuthorDto Author { get; set; }

   10 

   11         public virtual DateTime DateAdded { get; set; }

   12 

   13         public virtual DateTime DatePublished { get; set; }

   14 

   15         public virtual DateTime DateUpdated { get; set; }

   16 

   17         public virtual string Title { get; set; }

   18 

   19         public virtual string ShortDescription { get; set; }

   20 

   21         public virtual string Body { get; set; }

   22 

   23         public virtual bool IsFrontPage { get; set; }

   24 

   25         public virtual bool IsPublished { get; set; }

   26     }

 

The Test

Now before I get into the test, at this point I should probably acquaint myself with the idea of lazy loading verses eager loading.  If you look at the two class above, the Author class has a collection of NewsItems classes and each of the NewsItem classes has a Author class which has a collection NewsItem classes, etc, etc, etc…

To get around this circular mapping, NHibernate uses the Proxy Pattern so that NewsItem class is not actually loaded until asked for in the code.  I can either get all the collection classes up front (eager loading) or I can get the class when I need them (lazy loading).  David Hayden wrote a nice explanation about the ramifications of either one using LightSpeed that you can read here.

I state that now, because I want to test that if I search for an author using a user id that I will get a collection of news items back for that author.  So since I am using lazy loading, I am not actually going to make to database calls for the news items until I inspect the collection of news items in the authors object I get back.

So here is the test:

  104         [TestMethod]

  105         public void NHibernateCanGetNewsItemsBySpecifiedUserId()

  106         {

  107             const string userId = "testuser";

  108             var target = new NHibernateDataProvider(session);

  109             var authors = target.GetAuthorsBy(userId);

  110 

  111             Assert.IsTrue(authors.Count > 0, "Authors count is not greater than 0");

  112             Assert.IsTrue(authors[0].NewsItems.Count >0, "Author's news items count is not greater than 0");

  113             Assert.IsFalse(authors.Count > 1, "Retrieved too many authors");

 

I am testing that my function GetAuthorsBy will return a collection of NewsItems.

Here is the function:

   42         public IList<AuthorDto> GetAuthorsBy(string userId)

   43         {

   44             return _session.CreateCriteria(typeof(AuthorDto))

   45                 .Add(Restrictions.Eq("UserName", userId))

   46                 .SetResultTransformer(new DistinctRootEntityResultTransformer())

   47                 .List<AuthorDto>();

   48 

   49         }

This function is using the NHibernate API to query the Author table by passing the userid.

Here is what is happening here:

·          CreateCritera starts off by asking what class I want to return.  I am telling to return a collection of Authors.

·          To add the Where Clause, I use the Add extension function and pass in the Restrictions.Eq function passing the property name and matching value.

·          By default, it is possible for me to get author “A” and then get author “B” and then again get author “A” in the collection, each with their own set of news items.  To avoid this I want to combine all duplicates so they only show up once.  Essentially this would be the equivalent to the DISTINCT statement in SQL.  I can do this using the SetResultTransformer extension function passing in the DistinctRootEntityResultTransformer.  This function will take the collection and merge the duplicates together (this done in memory not in the database).  Ayende gives some other examples and explanations here.

·          Finally the List extension tells NHibernate that I want a strongly types IList<AuthorDTO> class.

So when the function is called the following query is made to the database.

NHibernate: SELECT this_.AuthorId as AuthorId1_0_, this_.UserName as UserName1_0_, this_.FirstName as FirstName1_0_, this_.LastName as LastName1_0_, this_.Password as Password1_0_, this_.EmailAddress as EmailAdd6_1_0_, this_.DateAdded as DateAdded1_0_, this_.DateUpdated as DateUpda8_1_0_, this_.IsActive as IsActive1_0_ FROM Author this_ WHERE this_.UserName = @p0; @p0 = 'testuser'

Then when the test does an assert on the NewsItem count the following query is made.

NHibernate: SELECT newsitems0_.AuthorId as AuthorId1_, newsitems0_.NewsId as NewsId1_, newsitems0_.NewsId as NewsId0_0_, newsitems0_.AuthorId as AuthorId0_0_, newsitems0_.DateAdded as DateAdded0_0_, newsitems0_.DateUpdated as DateUpda4_0_0_, newsitems0_.DatePublished as DatePubl5_0_0_, newsitems0_.Title as Title0_0_, newsitems0_.ShortDescription as ShortDes7_0_0_, newsitems0_.Body as Body0_0_, newsitems0_.IsFrontPage as IsFrontP9_0_0_, newsitems0_.IsPublished as IsPubli10_0_0_ FROM News newsitems0_ WHERE newsitems0_.AuthorId=@p0; @p0 = '1'

In the next post I will look at testing the Service layer using Rhino Mocks and possibly throw in my first example of how I am going to use Unity.

 

 

Jan
13
2009

Creating a Web Application Using MVC, Unity and NHibernate – Part 1

 

Introduction

 

I thought it would be useful to document what it would take to incorporate building a web application that is designed with the Microsoft MVC framework, that also incorporated using NHibernate as a O/R Mapper and uses Microsoft Unity as the Dependency Injection, IoC framework.  I must confess, I am not an expert of any of these tools, so I welcome feedback from the community.  The reason I am doing this to begin with, is there is not a whole a lot of documentation on of this “stuff” by themselves let alone all together, so I am hoping fill a little bit of that void.  If you think there are better approaches then what I am doing, feel free to provide feedback.   I am basically doing this for my own enrichment and if it is also helpful to the community, then—well—even better.

Since this going to have to be a series of posts, I will probably not cover every aspect of this application all at once, so if what you are looking for is not in this post, then be patient and maybe I will get to it in a later one.  As a matter of fact, since I am going to be adhering to a test first approach (red, green, refactor), I will probably not get to the MVC framework until several posts from now.  The first few posts will only be covering tests.

 

Setting up NHibernate

 

I have mentioned this before, but if you are new to NHibernate and don’t know how to get started, I highly recommend the Summer of NHibernate videos by Stephen Bohlen.  The download of NHibernate is located here.  Once downloaded, the first thing I need to do is put the NHibernate schema files in the Visual Studio schema folder (my folder is located here C:\Program Files\Microsoft Visual Studio 9.0\Xml\Schemas) so I can get intellisense on the configuration and mapping files. 

In general, for all the external libraries, it is useful to place them all in a folder location relative to, or just inside your solution so, for example, if you are using source control the other developer machines will pick up the references without any problems.  Thus, I am doing the same with this application, and will then be referencing the NHibernate.dll in all my relevant projects.  In my case, I am only going to have a Web, Core, and Test project so I will reference it for now in the Core and Test project.  I will probably need to reference in the web project once I set up Unity, but I will leave it out for now.

The next thing I will need to do is to create a NHibernate configuration file.  One of the cool concepts NHibernate follows is the Convention over Configuration paradigm.  That is, as long as I follow a certain convention, I will not need to configure certain aspects of NHibernate when setting it up.  So if I create a configuration file and name it hibernate.cfg.xml, then set is build action to copy to output folder, I will not need to tell NHibernate where the configuration file is.  Note:  I tried this in a Microsoft Team Test project and for some reason the test project would not copy that file to the output folder so I ended up having to configure the path anyway.

Here is the configuration file that is in the root directory of my test project.

    1 <?xml version="1.0" encoding="utf-8" ?>

    2 <hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">

    3   <session-factory name="NHibernate.Test">

    4     <property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>

    5     <property name="connection.connection_string">

    6       Data Source=(local);Initial Catalog=News;Persist Security Info=True;User ID=my_dev;Password=my_dev

    7     </property>

    8     <property name="adonet.batch_size">10</property>

    9     <property name="show_sql">true</property>

   10     <property name="dialect">NHibernate.Dialect.MsSql2005Dialect</property>

   11     <property name="use_outer_join">true</property>

   12     <property name="command_timeout">444</property>

   13     <property name="query.substitutions">true 1, false 0, yes 'Y', no 'N'</property>

   14     <mapping assembly="News.Core"/>

   15   </session-factory>

   16 </hibernate-configuration>

 

Notice that in the root tag that since I place the NHibernate schema files in the Visual Studio schema folder I now have access to intellisense.  You can see the property setting definitions here, but here are the important nodes

·          The show_sql property is going to be useful when debugging so I can see the SQL statements.  I will turn this off in production because it is expensive.

·          The dialect is going to tell NHibernate to what specific database language and version it is going to translate the SQL to.

·          The mapping tells NHibernate where the mapping files and classes are located.

Once the configuration file is created, I then can call it from my code and create the ISessionFactory.  I will talk about my approach later in another post, but essentially because ISessionFactory is expensive to create and there also some threading concerns with creating it; I am going to create it differently in the test project than in the web project.  In both cases, I am going to implement an interface I created call ISessionFactoryManager.  This interface, as of now, will have one method called GetSessionFactory.  The code in my test project looks like this.

    1 using News.Core.Data;

    2 using NHibernate;

    3 using NHibernate.Cfg;

    4 

    5 namespace News.Web.Tests

    6 {

    7     internal class TestSessionFactoryManager : ISessionFactoryManager

    8     {

    9         public ISessionFactory GetSessionFactory()

   10         {

   11             string path = @"C:\Projects\News\Src\News.Web.Tests\hibernate.cfg.xml";

   12             var cfg = new Configuration();

   13             cfg.Configure(path);

   14             return cfg.BuildSessionFactory();

   15 

   16         }

   17     }

   18 }

 

 Note:  If I want, I can also add properties at run time.  For example, say my connection string is stored in a super secret place; I could get it and set the ISessionFactory with the following code.  It just has to be done before the BuildSessionFactory is called, because once called, it cannot be changed.

  15             cfg.Properties.Add("connection.connection_string",connectionString);

 

Once the BuildSessionFactory method is called, Nhibernate goes and retrieves the configuration file, and also the Mapping files (I will discuss later) and returns the session factory.  I now can open sessions to the database and do whatever database CRUD I need to do.

Mapping Tables to Classes

 For my example, I am going to have two tables with the following schema:


For this post, I am only going to worry about the News table.  Again, using convention over configuration, I have mapping file named NewsItemDto.hbm.xml so I do not have to tell NHibernate where it is.  I need to make sure this file is an embedded resource, so it can be referenced.  The content of the file looks like this:

    1 <?xml version="1.0" encoding="utf-8" ?>

    2 <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="News.Core" namespace="News.Core.Dto">

    3   <class name="News.Core.Dto.NewsItemDto, News.Core" table="News">

    4     <id column="NewsId" name="NewsId" type="long" unsaved-value="0">

    5       <generator class="native"></generator>

    6     </id>

    7     <property column="AuthorId" name="AuthorId" type="long" not-null="true"/>

    8     <property column="DateAdded" name="DateAdded" type="DateTime" not-null="true"/>

    9     <property column="DateUpdated" name="DateUpdated" type="DateTime" not-null="true"/>

   10     <property column="DatePublished" name ="DatePublished" type="DateTime" not-null="true" />

   11     <property column="Title" name="Title" type="string" not-null="true"/>

   12     <property column="ShortDescription" name="ShortDescription" type="string" not-null="false"/>

   13     <property column="Body" name="Body" type="string" not-null="true"/>

   14     <property column="IsFrontPage" name="IsFrontPage"/>

   15     <property column="IsPublished" name="IsPublished"/>

   16   </class>

   17 </hibernate-mapping>

 

Again, the root references the NHibernate mapping schema which will give me intellisense.  You can see all the property settings here.  In the class, I tell it the namespace and assembly name where the class is located.  The ID identifies the primary key of the table.  By setting the generator attribute to native, I am telling NHibernate that the field is an identity field and the value is created by the database.

Here is the code for the class:

    5     public class NewsItemDto

    6     {

    7         public virtual long NewsId { get; set; }

    8 

    9         public virtual long AuthorId { get; set; }

   10 

   11         public virtual DateTime DateAdded { get; set; }

   12 

   13         public virtual DateTime DatePublished { get; set; }

   14 

   15         public virtual DateTime DateUpdated { get; set; }

   16 

   17         public virtual string Title { get; set; }

   18 

   19         public virtual string ShortDescription { get; set; }

   20 

   21         public virtual string Body { get; set; }

   22 

   23         public virtual bool IsFrontPage { get; set; }

   24 

   25         public virtual bool IsPublished { get; set; }

   26     }

 

The properties are all virtual so NHibernate can utilize the proxy pattern for performance reasons.  This will come more into play when use the Authors table in following posts.

 

Creating the test

 

As a part of the buildup and teardown of my NHibernate tests, I will have each of my test create a session object that connects to the data base before the test starts and then close the session object once the test finishes.

    1 using News.Core.Data;

    2 using Microsoft.VisualStudio.TestTools.UnitTesting;

    3 using NHibernate;

    4 

    5 namespace News.Web.Tests

    6 {

    7     public class DatabaseBaseTest

    8     {

    9         private ISessionFactoryManager sessionFactoryManager = new TestSessionFactoryManager();

   10         protected ISession session;

   11 

   12 

   13 

   14         [TestInitialize]

   15         public void SetUp()

   16         {

   17             

   19             session = sessionFactoryManager.GetSessionFactory().OpenSession();

   20         }

   21 

   22         [TestCleanup]

   23         public void CleanUp()

   24         {

   25             session.Close();

   26             session = null;

   27         }

   28     }

   29 }

 

Now that I have Session I can create my first test.  This test will simply return 1 record from the NewsItem table by passing the NewsItemId parameter.

   78         [TestMethod()]

   79         public void GetNewsItemByItemIdShouldReturnMatchingTitle()

   80         {

   81             var target = new NHibernateDataProvider(session);

   82             const string expected = "test";

   83             const int itemId = 2;

   84             Assert.AreEqual(expected, target.GetNewsItemByItemId(itemId).Title);

   85         }

 

My database has a record which contains the Title value “test”.

 

The Repository

 

The data access code that gets the records looks like this:

   17         public NewsItemDto GetNewsItemByItemId(long newsItemId)

   18         {

   19             return _session.Get<NewsItemDto>(newsItemId);

   20 

   21         }

 

 

In the next post I will add the Authors table to the mix and some functionality retrieving those joined records.

Aug
7
2008

Usng Unity with a WCF Service

Introduction

In a provious blog post, I talked about using Unity in a multi-layer web application.  You could see in that example, the Application_OnStart event worked out as a very nice place to configure the Unity Container so it could be used throughout the application.  But what do you do if you have a WCF Service project, and you want to configure your service to access the same container?  In this case, you do not have access to any application events, nor is there a web context you pull from.

Oran Dennison has a nice example of accomplishing this task using Spring.Net, and it turns out there is not much to change if you want to use it with Unity also.

Step 1 - Creating an custom InstanceProvider that resolves the service.

The IInstanceProvider controls the creating and recycling of the service when it is requested.  We can impliment this interface and pass in a UnityContainer and resolve the service that is being requested.

 

    1 using System;

    2 

    3 using System.ServiceModel;

    4 using System.ServiceModel.Channels;

    5 using System.ServiceModel.Dispatcher;

    6 

    7 using Microsoft.Practices.Unity;

    8 

    9 namespace UnitySample

   10 {

   11     public class UnityInstanceProvider : IInstanceProvider

   12     {

   13         public UnityContainer Container { set; get; }

   14         public Type ServiceType { set; get; }

   15 

   16         public UnityInstanceProvider()

   17             : this(null)

   18         {

   19         }

   20 

   21         public UnityInstanceProvider(Type type)

   22         {

   23             ServiceType = type;

   24             Container = new UnityContainer();

   25         }

   26 

   27         #region IInstanceProvider Members

   28 

   29         public object GetInstance(InstanceContext instanceContext, Message message)

   30         {

   31             return Container.Resolve(ServiceType);

   32         }

   33 

   34         public object GetInstance(InstanceContext instanceContext)

   35         {

   36             return GetInstance(instanceContext, null);

   37         }

   38         public void ReleaseInstance(InstanceContext instanceContext, object instance)

   39         {

   40         }

   41 

   42         #endregion

 You can see above when the GetInstance is evoked by a service, the service's type is passed into the contructor and resolved by the UnityContainer.

 Step 2 - Create a custom ServiceBehavior object to plug in our InstanceProvider

Now that we have a cutom instance provider we need to way to insert this new provider at run time, and it is IServiceProvider that is going to provide this for us.  When the ApplyDispatchBehaviour is evoked, the code will loop through the collection of EndPoints in our project and pass the corresponding service type to the instance provider.

    1 using System.ServiceModel;

    2 using System.ServiceModel.Channels;

    3 using System.ServiceModel.Description;

    4 using System.ServiceModel.Dispatcher;

    5 

    6 using Microsoft.Practices.Unity;

    7 using System.Collections.ObjectModel;

    8 

    9 namespace UnitySample

   10 {

   11     public class UnityServiceBehavior : IServiceBehavior

   12     {

   13         public UnityInstanceProvider InstanceProvider

   14         { get; set; }

   15 

   16         private ServiceHost serviceHost = null;

   17 

   18         public UnityServiceBehavior()

   19         {

   20             InstanceProvider = new UnityInstanceProvider();

   21         }

   22         public UnityServiceBehavior(UnityContainer unity)

   23         {

   24             InstanceProvider = new UnityInstanceProvider();

   25             InstanceProvider.Container = unity;

   26         }

   27         public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)

   28         {

   29             foreach (ChannelDispatcherBase cdb in serviceHostBase.ChannelDispatchers)

   30             {

   31                 ChannelDispatcher cd = cdb as ChannelDispatcher;

   32                 if (cd != null)

   33                 {

   34                     foreach (EndpointDispatcher ed in cd.Endpoints)

   35                     {

   36                         InstanceProvider.ServiceType = serviceDescription.ServiceType;

   37                         ed.DispatchRuntime.InstanceProvider = InstanceProvider;

   38 

   39                     }

   40                 }

   41             }

   42         }

   43 

   44 

   45         public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) { }

   46 

   47 

   48         public void AddBindingParameters(

   49             ServiceDescription serviceDescription,

   50             ServiceHostBase serviceHostBase,

   51             Collection<ServiceEndpoint> endpoints,

   52             BindingParameterCollection bindingParameters)

   53         {

   54         }

   55 

   56     }

   57 }

 Step 3 - Create a Custom Service Host that will add the new behavior

The ServiceHost object basically provides the mechamism to "load a service, configure endpoints, apply security settings, and start listeners to handle incoming requests."  We can derive a custom ServiceHost class that in our case that will also add the functionality of adding our custom Service Behavior to it.

    1 using System;

    2 using System.ServiceModel;

    3 

    4 using Microsoft.Practices.Unity;

    5 

    6 namespace UnitySample

    7 {

    8     public class UnityServiceHost : ServiceHost

    9     {

   10         public UnityContainer Container { set; get; }

   11 

   12         public UnityServiceHost()

   13             : base()

   14         {

   15             Container = new UnityContainer();

   16         }

   17 

   18         public UnityServiceHost(Type serviceType, params Uri[] baseAddresses)

   19             : base(serviceType, baseAddresses)

   20         {

   21             Container = new UnityContainer();

   22         }

   23 

   24         protected override void OnOpening()

   25         {

   26             if (this.Description.Behaviors.Find<UnitySample.UnityServiceBehavior>() == null)

   27                 this.Description.Behaviors.Add(new UnityServiceBehavior(Container));

   28 

   29             base.OnOpening();

   30         }

   31 

   32 

   33 

   34     }

   35 }

 When the service host starts it will check to see if the custom ServiceBehaviour has already been added and if it has not, then it will be added to Behavior collection.

Step 4 - Creating the Custom ServiceHostFactory

In IIS our Host will be created dynamically, so we need to use the ServiceHostFactory which uses the Factory Pattern behind the scenes to return the custom Service Host we need.

    1 using System;

    2 using System.ServiceModel;

    3 using System.ServiceModel.Activation;

    4 using Microsoft.Practices.Unity;

    5 using Microsoft.Practices.Unity.Configuration;

    6 using System.Configuration;

    7 

    8 namespace UnitySample

    9 {

   10     public class UnityServiceHostFactory : ServiceHostFactory

   11     {

   12         protected override ServiceHost CreateServiceHost(

   13                                           Type serviceType, Uri[] baseAddresses)

   14         {

   15             UnityServiceHost serviceHost = new UnityServiceHost(serviceType, baseAddresses);

   16             UnityContainer container = new UnityContainer();

   17             serviceHost.Container = container;

   18 

   19             //configure container

   20             UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");

   21             section.Containers.Default.Configure(serviceHost.Container);

   22 

   23             return serviceHost;

   24         }

   25     }

   26 }

Note that I am using the same Unity Configuration from my previous post.

Step 5 - Add a Reference to ServiceHostFactory in the *.svc file

    1 <%@ ServiceHost Language="C#" Debug="true" Service="UnitySampleService" CodeBehind="~/App_Code/UnitySampleService.cs"

    2     Factory="UnitySample.UnityServiceHostFactory" %>

Step 6 - Inject Your Objects on the Service

    1 using System;

    2 using System.Collections.Generic;

    3 using System.Linq;

    4 using System.Runtime.Serialization;

    5 using System.ServiceModel;

    6 using System.Text;

    7 using UnitySamples.Core.Controllers;

    8 using UnitySamples.Core.Dto;

    9 

   10 // NOTE: If you change the class name "UnitySampleService" here, you must also update the reference to "UnitySampleService" in Web.config.

   11 public class UnitySampleService : IUnitySampleService

   12 {

   13     private IProcessUserController controller;

   14 

   15     public UnitySampleService(IProcessUserController controller)

   16     {

   17         this.controller = controller;

   18     }

   19 

   20     public void DoWork(User user)

   21     {

   22         controller.RegisterUser(user);

   23     }

   24 

   25 }

 

 

 

Aug
4
2008

EntLib4.1 and Unity 1.2 project started

The next release will inlcude the following:

-         Collections support in the Unity Application Block (Unity dependency injection container)

-         Improved support for generics in Unity

-         Interception mechanism in Unity (including integration with the Policy Injection Application Block)

-         Improved type picker of the config tool (this one needed a face lift for a long time)

-         Debugging visualizer (to allow for easy navigation of mappings, corresponding lifetime policies as well as container extensions).

 

  Here is the post:

http://blogs.msdn.com/agile/archive/2008/08/03/entlib4-1-kickoff.aspx

 

Aug
2
2008

Using Microsft Unity Wire Up a Multi Layer Web Application

Introduction

If you have looked around recently, you may have noticed the latest craze seems to be the poliferation of the IofC / Dependency Injection frameworks for the .Net framework.  Now with the release of Enterprise Library 4.0, Microsoft has released a their own updated version that I really like, albeit I have used Enterprise Library many years now since the inception of the Data Access application block.  But before I get ahead of myself, I suppose the question should be asked, "why should I use a dependancy container at all?"

Benifets of Dependency Injection

  • Don't talk to strangers!  When I was learning to code this was drilled into me by my mentors.  The idea is that your object should not know anything about any other object.  The technical term is "loose coupling" meaning you should be able to take out one object and replace it with another object and as long as it adheres to the same interface there should not be the need for any code changes any where else in your application.
  • Configurability.  It would be nice that if instead Foo, I now want to talk to FooFoo, I should be ably to just reference a new object and change the configuration to point to that new object.
  • Testabiliy.  I should be able to test all functionality even if the function relys on concrete dependencies such as connection to databases or IO read/writes.  With dependency injection, it is easier to do that because you can mock those object since they are now Interfaces. 
  • Another aspect that I like, especially as some who is responsible for reviewing code, is it forces you make interfaces for all you concrete classes which addresses another OO coding rule and that is you should always reference an interface and not a concreate object.

Model View Presenter Pattern and Unity

Lets get to work and create a simple application.

I will address how Model View Presenter works in another blog but basically the benifet of the pattern is its good way to separate UI from functional code not related to UI.

At any rate I have created a registration webpage, that will take the users info and pass it back several layers to a database or service layer.

   10     <div>

   11         New User Registration

   12         <br />

   13         First Name:

   14         <asp:TextBox ID="txtFirstName" runat="server"></asp:TextBox><br />

   15         Last Name:

   16         <asp:TextBox ID="txtLastName" runat="server"></asp:TextBox><br />

   17         Phone Number:

   18         <asp:TextBox ID="txtPhone" runat="server"></asp:TextBox><br />

   19         Email Address:

   20         <asp:TextBox ID="txtEmail" runat="server"></asp:TextBox>

   21         <br />

   22         <asp:Button ID="Button1" runat="server" Text="Button" />

   23     </div>

To use Unity first lets wire it up to Global.asax page so that when application first loads up it will get the Unity configuration and load into memory and cache it.The next step is to set up the view and the presenter.  On his PNPGuidance site, David Hayden gives a really neat approach to use Generics to inject the View onto the Presenter and vice versa, so I am going to do the same thing here.  The only difference is I am going to register the objects using the configuration file instead through code.  David Hayden also has sample of how to do that here.  With initial base work completed, I now have a view that my registation page can impliment which looks like this.

    8     public interface IRegistrationView

    9     {

   10         string FirstName { get;  }

   11         string LastName { get;  }

   12         string Phone { get;  }

   13         string Email { get;  }

   14 

   15         event EventHandler RegisterClicked;

   16     }

The webpage impliments this interface which I can then pass to the presenter.

   26         #region IRegistrationView Members

   27 

   28         public string FirstName

   29         {

   30             get { return txtFirstName.Text; }

   31         }

   32 

   33         public string LastName

   34         {

   35             get { return txtLastName.Text; }

   36         }

   37 

   38         public string Phone

   39         {

   40             get { return txtPhone.Text; }

   41         }

   42 

   43         public string Email

   44         {

   45             get { return txtEmail.Text; }

   46         }

   47 

   48         public event EventHandler RegisterClicked;

   49 

   50         #endregion

   51 

   52         protected void Button1_Click(object sender, EventArgs e)

   53         {

   54             if (RegisterClicked != null)

   55                 RegisterClicked(this, e);

   56         }

The presenter handles the RegisteredClick event which I can use to pass the user down the chain via dependency injection.  You can see in my presenter code that I am injecting the controller object which is the next object down the chain.  It is assumed that this object would process and validate the data, applying any rules before it would then pass it to service layer.

   13         IProcessUserController controller;

   14 

   15         public RegistrationPresenter(IProcessUserController controller)

   16         {

   17             this.controller = controller;

   18         }

   19 

   20 

   21         public override void OnViewInitialized()

   22         {

   23             base.OnViewInitialized();

   24             this.View.RegisterClicked += new EventHandler(View_RegisterClicked);

   25 

   26         }

   27 

   28         void View_RegisterClicked(object sender, EventArgs e)

   29         {

   30             User user = new User();

   31             user.Email = this.View.Email;

   32             user.FirstName = this.View.FirstName;

   33             user.LastName = this.View.LastName;

   34             user.Phone = this.View.Phone;

   35             controller.RegisterUser(user);

   36         }

 Here is the controller code.  It again injects the service/proxy class in the constructor passing the request further down the chain.

    9     public class ProcessUserController : IProcessUserController

   10     {

   11         private readonly IUserServiceProxy proxy;

   12 

   13 

   14         public ProcessUserController(IUserServiceProxy proxy)

   15         {

   16             //do some logic and other stuff here before passing to the service

   17             this.proxy = proxy;

   18         }

   19 

   20         #region IProcessUserController Members

   21 

   22         public void RegisterUser(UnitySamples.Core.Dto.User user)

   23         {

   24             proxy.InsertUser(user);

   25         }

   26 

   27         #endregion

   28     }

All this magic is happening via the details of the configuration file.  The controller class and the proxy class both are listed in the web.config unity section and when the configuration section is read, Unity determines where to inject what concrete class based on what interface is mapped to what class in the configuration file, and what interface is called for in the contructer of the calling class.

   21   <unity>

   22     <typeAliases>

   23       <!-- Lifetime manager types -->

   24       <typeAlias alias="singleton" type="Microsoft.Practices.Unity.ContainerControlledLifetimeManager, 

   25           Microsoft.Practices.Unity" />

   26     </typeAliases>

   27     <containers>

   28       <container>

   29         <types>

   30           <!-- Lifetime managers specified using the type aliases -->

   31           <type type= "UnitySamples.Core.Controllers.IProcessUserController, UnitySamples.Core"

   32               mapTo="UnitySamples.Core.Controllers.ProcessUserController, UnitySamples.Core">

   33             <lifetime type="singleton" />

   34           </type>

   35           <type type= "UnitySamples.Core.Service.IUserServiceProxy, UnitySamples.Core"

   36               mapTo="UnitySamples.Core.Service.UserServiceProxy, UnitySamples.Core">

   37             <lifetime type="singleton" />

   38           </type>

   39         </types>

   40       </container>

   41     </containers>

   42   </unity>