Thursday 20 May 2010

Learn NHibernate lesson 1 - setup and basic usage

disclaimer - at the moment, this post is in note format from a workshop I did, I need to it clean up, and add grammar

its an abstraction layered on top of database

ISesssion, unit of work pattern, same as Dataset in ADO.NET

a unit of work consists of:
Open session by getting from session factory
Do some work (session.add, session.delete)
flush the session

getting a session:
sessionfactory.opensession

how does session factory build itself?
uses configuration class to build it
config is throw away class[csharp]
ISessionfactory sf = new Configuration().Configure().BuildSessionFactory();

[/csharp]


vs 2008
if using xml onfig, drop nhibe xsd's in to vs intellisense directory
once hibernate mapping tag in config xml, will be able to use intellinsense for conifg xml[xml]
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembley="DataTransfer" namespace="DataTransfer">

[/xml]


with reference to NHibernate 1.2.1
1. Setup and basic usage pattern
xml config

mapping files tell nhibe how db maps to objects
relies on convention over configuration
case sensitive
default is to use convention which is "classname.hbm.xml"
one for each class, start with class name[xml]

<class name="DataTransfer.Customer, DataTransfer" table="Customer"> (Namepsapce.TypeName, Namespace)

[/xml]


must have an id tag (primary key or composite id)[xml]

<id name="CustomerId" column="CustomerId" type="Int32" unsaved-value="0">
<generator></generator>

</id>

[/xml]


(this tells nhibe how to generate value for the id, native means db will use its own capabilities to gen the id)[xml]

<property name="FirstName" column="FirstName" type="string" length="50" not-null="false"></property>

[/xml]


if no column name specified, nhibe will asume column is same name as property
deploying mapping files

set build action of hbm.xml in vs to embedded resource so they are compiled in to assemblies
using lutz roeders .NET refelctor you can see dissasemblies

all methods in classes should be virtual!

new up new configuration and session[csharp]

NHibernate.Cfg.Configuration config = new NHibernate.Cfg.COnfiguration();
config.configure();
NHibernate.ISessionfactory sf = config.BuildSessionFactory();
NHibernate.ISession session = sessionFactory.OPenSession();

[/csharp]


creating a dataaccess layer

getting an object from db by id[csharp]

public class NHIbernateDataProvider
{
public Datatransfer.Customer GetCustomerByID(int cumstomerId)
{
NHibernate.Cfg.Configuration config = new NHibernate.Cfg.COnfiguration();
config.configure();
NHibernate.ISessionfactory sf = config.BuildSessionFactory();
NHibernate.ISession session = sessionFactory.OpenSession();

//no generic get
return (DataTransfer.Customer)session.Get(typeof(Datatrasnfer.Customer), customerId);
//generic get
return session.Get<Datatransfer.Customer>(customerId);
}
}
[/csharp]


cleaning that up

configuration class only needed long enough to get a session factory[csharp]

using NHIbernate;
using DataTransfer;

public class NHibernateDataProvider
{
public Datatransfer.Customer GetCustomerByID(int cumstomerId)
{
ISessionfactory sf = (new Configuration()).Configure().BuildSessionFactory();
ISession session = sessionFactory.OpenSession();

return session.Get<Datatransfer.Customer>(customerId);
}
}

[/csharp]


test project for dataaccess layer

assume references addded.. and using statementsn included..
providing a connection string for NHibernate and other configuration

NHibernate configuration file belongs in project that is running code.. so needs to be included in the test project

XML File called "hibernate.config.xml"[xml]

<hibernate-configuration xmlns="urn:nhibernate-mapping-2.2">
<session-factory name="MyFavouriteSessionFactory"> (you could have an app that talks to differnt databases by addnig name to the session factory tag)
<property name="connection.provider">...
<property name="connection.connection_string">...
<property name="show_sql">true<property>
<mapping assembly="DataTransfer"/>
</session-factory>

[/xml]


you can see the defaults needed and structure by opening the nhibernate.config.xml that is downlaoded with NHibernate..

it includes things like query substitutionns, command timeout, drivers and other useful stuff..[csharp]

[TestFixture]
public class tests
{
[test]
public void CanGetCustomerById()
{
DataAccessLayer.NHibernateDataProvider provider = new DataAccessLayer.NHibernateDataProvider();
Assert.AreEqual(1, provider.GetCustomerId(1).CUstomerId);
}
}

[/csharp]


Show SQL
adding the <property name="show_sql">true<property> to your config file qill echo the sql statement (eg console output). so in the html report from MBUnit you wil see the sql generated by NHIbernate in the test results.

nhibernate generates parametirised sql so that sql server can generate cached execution plans. its also protection from sql injection

Learn NHibernate lesson 1 - setup and basic usage

disclaimer - at the moment, this post is in note format from a workshop I did, I need to it clean up, and add grammar

its an abstraction layered on top of database

ISesssion, unit of work pattern, same as Dataset in ADO.NET

a unit of work consists of:
Open session by getting from session factory
Do some work (session.add, session.delete)
flush the session

getting a session:
sessionfactory.opensession

how does session factory build itself?
uses configuration class to build it
config is throw away class[csharp]
ISessionfactory sf = new Configuration().Configure().BuildSessionFactory();

[/csharp]


vs 2008
if using xml onfig, drop nhibe xsd's in to vs intellisense directory
once hibernate mapping tag in config xml, will be able to use intellinsense for conifg xml[xml]
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembley="DataTransfer" namespace="DataTransfer">

[/xml]


with reference to NHibernate 1.2.1
1. Setup and basic usage pattern
xml config

mapping files tell nhibe how db maps to objects
relies on convention over configuration
case sensitive
default is to use convention which is "classname.hbm.xml"
one for each class, start with class name[xml]

<class name="DataTransfer.Customer, DataTransfer" table="Customer"> (Namepsapce.TypeName, Namespace)

[/xml]


must have an id tag (primary key or composite id)[xml]

<id name="CustomerId" column="CustomerId" type="Int32" unsaved-value="0">
<generator></generator>

</id>

[/xml]


(this tells nhibe how to generate value for the id, native means db will use its own capabilities to gen the id)[xml]

<property name="FirstName" column="FirstName" type="string" length="50" not-null="false"></property>

[/xml]


if no column name specified, nhibe will asume column is same name as property
deploying mapping files

set build action of hbm.xml in vs to embedded resource so they are compiled in to assemblies
using lutz roeders .NET refelctor you can see dissasemblies

all methods in classes should be virtual!

new up new configuration and session[csharp]

NHibernate.Cfg.Configuration config = new NHibernate.Cfg.COnfiguration();
config.configure();
NHibernate.ISessionfactory sf = config.BuildSessionFactory();
NHibernate.ISession session = sessionFactory.OPenSession();

[/csharp]


creating a dataaccess layer

getting an object from db by id[csharp]

public class NHIbernateDataProvider
{
public Datatransfer.Customer GetCustomerByID(int cumstomerId)
{
NHibernate.Cfg.Configuration config = new NHibernate.Cfg.COnfiguration();
config.configure();
NHibernate.ISessionfactory sf = config.BuildSessionFactory();
NHibernate.ISession session = sessionFactory.OpenSession();

//no generic get
return (DataTransfer.Customer)session.Get(typeof(Datatrasnfer.Customer), customerId);
//generic get
return session.Get<Datatransfer.Customer>(customerId);
}
}
[/csharp]


cleaning that up

configuration class only needed long enough to get a session factory[csharp]

using NHIbernate;
using DataTransfer;

public class NHibernateDataProvider
{
public Datatransfer.Customer GetCustomerByID(int cumstomerId)
{
ISessionfactory sf = (new Configuration()).Configure().BuildSessionFactory();
ISession session = sessionFactory.OpenSession();

return session.Get<Datatransfer.Customer>(customerId);
}
}

[/csharp]


test project for dataaccess layer

assume references addded.. and using statementsn included..
providing a connection string for NHibernate and other configuration

NHibernate configuration file belongs in project that is running code.. so needs to be included in the test project

XML File called "hibernate.config.xml"[xml]

<hibernate-configuration xmlns="urn:nhibernate-mapping-2.2">
<session-factory name="MyFavouriteSessionFactory"> (you could have an app that talks to differnt databases by addnig name to the session factory tag)
<property name="connection.provider">...
<property name="connection.connection_string">...
<property name="show_sql">true<property>
<mapping assembly="DataTransfer"/>
</session-factory>

[/xml]


you can see the defaults needed and structure by opening the nhibernate.config.xml that is downlaoded with NHibernate..

it includes things like query substitutionns, command timeout, drivers and other useful stuff..[csharp]

[TestFixture]
public class tests
{
[test]
public void CanGetCustomerById()
{
DataAccessLayer.NHibernateDataProvider provider = new DataAccessLayer.NHibernateDataProvider();
Assert.AreEqual(1, provider.GetCustomerId(1).CUstomerId);
}
}

[/csharp]


Show SQL
adding the <property name="show_sql">true<property> to your config file qill echo the sql statement (eg console output). so in the html report from MBUnit you wil see the sql generated by NHIbernate in the test results.

nhibernate generates parametirised sql so that sql server can generate cached execution plans. its also protection from sql injection

Learn NHibernate Lesson 2 - Exploring Query Methods and Syntaxes

disclaimer - at the moment, this post is in note format from a workshop I did, I need to it clean up, and add grammar

Part 2 More Query Methods and Syntaxes

first a refactor.. up until now we have been getting a session in every dataaccess layer method. we dont want to be doing this as each time we get teh session we are connecting to the db, and wiring up anything else needed.. a waste.. so, we'll start by making session a private member on the dataaccess layer.[csharp]

public class DataAccessProvider
{
private ISession session;

//we now call the getsession in the constructor to the class..

public DataAccessProvider ()
{
session = GetSession();
}

[/csharp]


now methods will look like the following:[csharp]

public IList<Customer> GetCustomerByFirstName(string firstname)
{
return session.CreateQuery("select from Customer c whre c.Firsname='" + firstname + "'").List<Customer>();
}

[/csharp]

getting distinct in HQL[csharp]

public IList<string> GetDistinctCustomerFirstnames()
{
return session.CreateQuery"select distinct c.Firstname from Customer c").List<string>();
}

[test]
public void CanGetDistinctCustomerFirstnames()
{
IList<string> firstnames;
provider.GetDistinctCustomerFirstnames();

IList<string> foundfirstnames = new List<string>();

foreach (string fn in firstnames)
{
if(foundFirstnames.Count != 0)
Assert.IsFalse(foundFirstNames.Contains(fn));

foundFirstNames.Add(fn);
}
}

[/csharp]

refactor test to use lambda expressions..[csharp]

[test]
public void CanGetDistinctCustomerFirstnames()
{
IList<string> firstnames;
provider.GetDistinctCustomerFirstnames();

foreach (string fn in firstnames)
{
Assert.AreEqual(1, firstnames.Count<string>(x => x == fn));
}
}

[/csharp]


GetDistinctCustomerFirstnames using criteria[csharp]

public IList<string> GetDistinctCustomerFirstnames()
{
return session.CreateCrtieria<Customer>
.SetProjection(Projections.Distinct(Projections.Property("Firstname")))
.List<string>();
}

[/csharp]

getting ordered names through HQL[csharp]

public IList<string> GetOrderedCustomerFirstnames()
{
return session.CreateQuery<Customer>("select from Customer c order by c.Firstname").List<Customer>();
.List<string>();
}

[/csharp]


getting ordered names through Criteria[csharp]

public IList<string> GetOrderedCustomerFirstnames()
{
return session.CreateCritera<Customer>
.AddOrder(new Order("Firstname", true))
.List<string>();
}

[/csharp]

getting counted names through HQL[csharp]

public IList<object[]> GetCountedCustomerFirstnames()
{
return session.CreateQuery<Customer>("select c.Firstname, count(c.Firstname) from Customer c group by c.Firstname").List<object[]>();
.List<string>();
}

[test]
public void CanGetCountedCustomerFirstnames()
{
IList<object[]> firstnameCounts = provider.GetCountedCustomerFirstnames();

Dictionary<String, int> expectedCounts = new Dictionary<string, int>();
expectedCounts.Add("steve", 3);
expectedCounts.Add("mike", 1);

foreach(object[] item in firstnameCounts)
{
Assert.AreEqual(expectedCounts[item[0].ToString()], item[1]);
}
}

[/csharp]

Wednesday 12 May 2010

SOLID Principles in programming

Hi,

this is my first post just to get started. I am only putting this up to do some analysis on Wordpress SEO.

S - Single responsibility principle, the notion that an object should have only a single responsibility.

O - Open/closed principle, the notion that “software … should be open for extension, but closed for modification”.

L - Liskov substitution principle, see also design by contract.

I - Interface segregation principle, the notion that “many client specific interfaces are better than one general purpose interface.”

D - Dependency inversion principle, the notion that one should “Depend upon Abstractions. Do not depend upon concretions.”
Dependency injection is one