Sunday, December 30, 2007

NHibernate through C#

NHibernate through C#

Why NHibernate?
NHibernate takes care of low level data handling, and offers excellent supports multiple DBs.

Here is a sample application on the same
Create a simple table with the following structure
Id int
Title nvarchar(50)
EventDate datetime

Once done, create a new windows project and name it as “WindowsHibSample”. Create a new folder and name it “Entity”. Within this folder create a new class “Event” with the
following structure

Some Basic Requirements
1. Please note that all fields should be marked “private” and their accessors and mutators to be marked “public virtual”
2. You should define a public empty constructor. Feel free to use it the way you want it. Incase there is no need of it for you, even then define it. That’s the way NHibernate wants


public class Event
{
private int _id;
private string _title;
private DateTime _date;

public Event()
{
}
public virtual int Id
{
get { return _id; }
set { _id = value; }
}
public virtual string Title
{
get { return _title; }
set { _title = value; }
}
public virtual DateTime Date
{
get { return _date; }
set { _date = value; }
}
}


Once the basic class is defined, we should include reference for NHibernate application.

Library References
I’m sure you have humpty location that offer a download for the same. Download the latest version of it and add a reference of it to your project
I have used NHibernate that has a runtime version “v2.0.50727” and Version “1.2.1.4000”. Please ensure you have either this or versions above this in your system

Once you have added reference, Add App.config to your application. You App.Config should be similar to the one mentioned below


<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="dataConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Data.Configuration.DatabaseSettings, Microsoft.Practices.EnterpriseLibrary.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null" />
<section name="nhibernate" type="System.Configuration.NameValueSectionHandler, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
</configSections>
<connectionStrings>
<add name="Connection String" connectionString="Database=SampleDb;Server=(local)\SQLEXPRESS;Integrated Security=SSPI;"
providerName="System.Data.SqlClient" />
</connectionStrings>
<nhibernate>
<add key="hibernate.connection.provider" value="NHibernate.Connection.DriverConnectionProvider" />
<add key="hibernate.dialect" value="NHibernate.Dialect.MsSql2005Dialect" />
<add key="hibernate.connection.driver_class" value="NHibernate.Driver.SqlClientDriver" />
<add key="hibernate.connection.connection_string" value="Database=SampleDb;Server=(local)\SQLEXPRESS;Integrated Security=SSPI" />
<add key="hibernate.connection.pool_size" value="1"/>
<add key="hibernate.show_sql" value="true"/>
<!--
value="Server=localhost;initial catalog=nhibernate;Integrated Security=SSPI" />
-->
</nhibernate>
</configuration>




Application configuration will initialize NHiberante for the application when our application starts. Our next step is to bind Event object to be persisted in DB with Hibernate XML. This is achieved by creating a new xml file with the name Event.hbm.xml in the same folder as Event.cs. Please ensure the name of the xml file exactly matches name of the class (“Event” in this case)

Event.hbm.xml I used is appended

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<class name="WindowsHibSample.Event, WindowsHibSample" table="Event">
<id name="Id" column="Id" type="Int32">
<generator class="assigned">
</id>
<property name="Title" column="Title" type="string" length="50">
<property name="Date" column="EventDate" type="DateTime">
</class>
</hibernate-mapping>


Once this is done, we are all set to write a program that wires Event.cs with Event.hbm.xml

For that to be achieved we should have a utility class for NHibernate that would open up a session, connection and close when all this is done

We could do this as such in every code that we write, but this could be better achieved by creating a utility class for this purpose. I have appended the class that I used


public class NHibernateUtil
{
private const string CurrentSessionKey = "nhibernate.current_session";
private static readonly ISessionFactory sessionFactory;
private static ISession currentSession;

static NHibernateUtil()
{
Configuration cfg = new Configuration();
cfg.AddAssembly("HibernateExamples");
sessionFactory = cfg.BuildSessionFactory();
currentSession = null;
}

public static ISession GetCurrentSession()
{
if (currentSession == null)
currentSession = sessionFactory.OpenSession();
return currentSession;
}

public static void CloseSession()
{
if (currentSession == null)
return;
currentSession.Close();
currentSession = null;
}

public static void CloseSessionFactory()
{
if (sessionFactory != null)
sessionFactory.Close();
}
}


We are all set to connect NHibernate with our application
I created a simple form with controls to accommodate/acquire EventId, name and date, added some validation to see if they in proper format etc.

I then created a simple DBHandler class that will handshake with NHibernateUtil class and pass on the object (Event) to be persited to NHibernate

Here is the sample code invoked on click of save button in my form


int eventId;
string eventTitle;
DateTime eventDate;

eventId = System.Convert.ToInt32(txtID.Text);
eventTitle = txtTitle.Text;
eventDate = System.Convert.ToDateTime(DateTime.Now);
EventPersistence ep = new EventPersistence(eventId, eventTitle, eventDate);
ep.SaveEvent();




EventPersistence class does the actual ground work of handshake with NHibernate. We could have all code of EventPersistence on button click itself, but that would make our application look really ugly, although you are free to do so, if you feel there are too many classes in the making


using System;
using System.Collections.Generic;
using System.Text;
using NHibernate;
using NHibernate.Cfg;
namespace WindowsHibSample
{
public class EventPersistence
{
private Event _evt;
public EventPersistence(int evtId, string evtTitle, DateTime evtDate)
{
_evt = new Event();
_evt.Date = evtDate;
_evt.Id = evtId;
_evt.Title = evtTitle;
}

public int SaveEvent()
{
if (_evt == null)
return -1;
Configuration cfg = new Configuration();
cfg.AddAssembly("WindowsHibSample");

ISessionFactory factory = cfg.BuildSessionFactory();
ISession session = factory.OpenSession();
ITransaction transaction = session.BeginTransaction();
//insert Record
session.Save(_evt);
// commit all of the changes to the DB and close the ISession
transaction.Commit();
session.Close();
return 0;
}
}




Our application is all set for execution. If you encounter any issues please feel free to login your comments or refer to the troubleshooting section below

I’ll add more examples on NHibernate shortly…..until then happy NHibernating……….

Troubleshooting
Mapping Exception was unhandled : Resource not found
Check to see if you have changed “Build Action Type” of .hbm.xml file to “Embedded Resource”

Mapping Exception was Unhandled: Could not compile the mapping document
If this is the error you receive, then you might have to do a little more of error tracking. Get complete error stack. Easiest way is execute the application, instead of debugging it and examine the complete details of the error. One of the major reason this shows up is mismatch of field names in the .hbm.xml file and fields in underlying class, this section is case-sensitive. If you have a field in you class as “Title“, but mapped in .hbm.xml as “title”, you will receive this error. To correct it ensure all fields and their mappings are right

NHibernate.DuplicateMappingException: Duplicate class/entity mapping Event
Specified class has already been loaded into memory and duplicate version of the same is being loaded explicitly/implicitly. Check for method configuration.AddClass(<>). NHibernate creates an instance of the class as and when it sees correct version .hbm.xml, and also loads it into memory, any effort to explicitly load will result in duplication

Could not save Object: Identifier Type Mismatch
Data types between C# object and DB don’t go well. Type mismatch includes even few simple changes like conversion from in to long and vice-versa. There should be no scope for type mismatch in our object definition to clear this error. More over this is ADOException hence debugging and identifying cause should be much easier, for people who have worked in ADO.

Friday, December 14, 2007




WPF



A productive, unified approach to UI, media and documents to deliver unmatched user experience




Architecture of WPF








Let's get into some simple exercises on WPF





A simple example on creating Groupbox, expander controls









An array of controls - Labels, List, Buttons, Statusbars etc…











Example for command





Commands are the tasks to be executed. Command Binding links command to application logic. Command source ensues the flow and Command target is where the action/activity is being performed
If we have to execute Open document. Facility for the same has been provided through File->Open, Toolbutton, a button control at the bottom of the window and finally as context menu item. Managing all of them enabling/disabling could be a lot of pain. Trough Command, it is an easy implementation
We have several in-built commands like Application, Edit, Navigation, Media etc…Apart from this, we will be also able to create our own custom commands, shortly I'll add few samples on custom commands too








Code behind for the above application is










Example to show Bubling and tunning of events




Steps to reproduce are

  1. Create a simple application with a label containing a label, image and label in sequence

  2. Generate click event for all controls. Both container and contained

  3. Provide MessageBox for the click event on each of the control and in the code behind, do not set evenHandled property to True.


You'll see there is tunneling of events



To see bubling


  1. Same as step 1

  2. Generate Click event for the top level label control alone

  3. On clicking the label control, though you'd have clicked on the internal label/image control, only the outter label control reacts. This is because, the controls deep inside, check to see their event handling, if they do not have any corresponding handlers, they pass it on to the immediate parent, until the message/event is handled. This is no different from the way MFC/Win32 has been handling events in the past. Just theat it's new to a selected commnunity of .NET developers




Sample for the above is appended







Code behind for the application is appended







In the process you'll also notice few other operations like Popup control Transperant window creation, non-rectangular window creation, manipulating registry etc




Popup control creation






From code behind set the following code

popup1.IsOpen = true;






Registry Manipuations







Transparent window creation










Non-rectangular window









Data Binding




We can bind one controls value into another control so that we are able to see value reflection. Say for e.g. we have a slider control to adjust volume and a text control to directly key in required volume. If the values entered in one do not reflect on the other, than it has no value. A similar example has been displayed below. Enter a value in text, see it's reflection in slider and vice-versa.




There can be more interesting work on this Two-way reflections and Onewaysource. I'll add samples for both of them shortly





We can also bind classes so that we could read data from DB into these classes. Tie these classes with forms/pages, so that respective controls are populated accordingly


Let's consider a simple class as the following




We create a form to display above details. Way we would do it is connect to DB fetch records and manually populate fetched records into fields.


Before we populate into fields, let's take a look at the DB class






Once the instance of the class is populated with data from DB, we need to display them in form. Take a look at the form population





Code behind for the form





Application Configuration reader






Here ini this example we have pulled just a single record. Shortly I'll add more items on to populate multiple records into List, Combo and grid controls






XBAP



XBAP has been around for some time and there are a lot of questions to be answered here. I see there will be a lot of stuff to be added here. I wouldn't be surprised if all those to do items are added as XBAP solutions



    Here is a way you create XBAP application

  1. From Visual Studio 2008, select File->New Project and select "WPF Browser Application"

  2. Give it a name, and click on OK

  3. Open Page1.XAML and fill it with the following code







From the build menu select Publish and accept default options and click on Finish


Visual Studio take some time to copy files into inetput/wwwroot folder, once done, Visual Studio opens up brower and shows the application executing as a web application


Here are some questions that are answered


How is it different from aspx application/pages

Well, this is a lot different from them. In the sense UI is rendered as XML. This means a lot. As both windows and XBAP can share same code. Say we create a windows application (using WPF) and on the way, client requests for a similar web application. On a normal course (.NET 2.0/1.1..) we need a fresh development for the same and achieving it can be time consuming, especially when we have some complex implementation around Grid controls. We can easily get away from them, as we have plenty of reuse. All that you need to do here is copy XAML file from windows aplpication and load it into your new WPF Browser application. And if you have been one of those nice developers who has kept UI away from underlying application, then you can continue to use the sasme code for Browser application. Now look at the time for acheving this milestone, I'm sure your PM would prmote you soon, and your client would be impressed by your prowess.
This is one of the biggest and greatest changes from .NET 2.0



Can I have all the controls that are supported in Windows get alon with XBAP?

Majority of the controls are supported. I'll keep myself occupied with more such research and keep releasing them here. Please watch out. For now, pathience and Shanthi :



Are there any restrictions on XBAP?

Yes, all those restrictions on browser applications apply to XBAP too



Can XBAP run on bowsers other than IE?

Need to find out. Will update soon



Do client systems need .NET 3.0/5 to execute this?

Need to find out. Will update soon



Now let's sit back and taste XBAP


In the sample I had showed above, you would have seen three buttons pointing to Page 2, page 3 and Page 4. But where are they. I've put just some simple form controls into XBAP and created these pages. More is to come shortly. What impressed me was the navigation system and the way once page can be contained into another. Thos this sample do not have any thing in terms of containemnet, I do have bits of them coming in the end of the page, so please sit tight till then


Page2.xaml






Page3.xaml






Page4.xaml





















Do we always need to use only Hyperlink for navigation between Pages?

No. Here is a sample on other choices






Containing One page in another

A simple way of achieving this is mentioned below. Sometime Visual Studio crashes on code as below. Looks like a bug that needs Microsoft attention. As Visual Studio 2008 is in Beta version and is strong otherwise, I'm sure this would get corrected eventually




There is more to be added to show better navigation and usage of window controls like toolbars, menus, passing data between pages, accessing data across pages ets. You'll soon see them here. My hands are itching to go on….