Thursday, January 21, 2010

WPF - How to setup the height and width of a control based on the current window size?


I tried to set the width and height of my WPF control based on the current window size using data binding and value converters.
This is how I did that.
<Window x:Class=" Blogsprajeesh.Blogspot.WPFSamples.SetControlSizeView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:local="clr-namespace:Blogsprajeesh.Blogspot.WPFSamples "
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Name="mainWindow"
    Title="SetControlSizeView" Height="300" Width="575">
    <Window.Resources>
        <local:HeightConverter x:Key="heightConverter" />
    Window.Resources>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
        Grid.RowDefinitions>
        <TextBlock Background="RoyalBlue"
                   Height="{Binding ElementName=mainWindow,
                                Path=ActualHeight,
                                Converter={StaticResource heightConverter},
                                ConverterParameter=3}"
                   Text="Some sample text" Grid.Row="0"
                   VerticalAlignment="Center" />
    Grid>
Window>
IValueConverter implementation
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
    double __height;
    double __paramValue;

    if(double.TryParse(value.ToString(), out __height))
    {
        if (double.TryParse(parameter.ToString(), out __paramValue))
            return __height / __paramValue;
        else
            return __height / 2;
    }
    return 25;
}

Thursday, January 14, 2010

NHibernate – Creating the BaseRepository (Part 8)


Before creating repositories for each domain entities in our model, we will work on a base repository to define the operations that can be performed on all the entities in our model. It will be from this base repository the domain specific entity repositories inherit from.
My IRepositoryinterface is defined as

public interface IRepository where TEntity : BaseEntity
{
    void Add(TEntity entity);
    void Save(TEntity entity);
    void Remove(TEntity entity);
    TEntity GetById(KId id);
    IList GetAll();
    IList FindAllWithMultipleConditions(IList<Expression<Funcbool>>> searchCriterias);
    TEntity First(Expression<Funcbool>> searchCriteria);
    IList FindAll(Expression<Funcbool>> searchCriteria);
}

The repository class implements the IRepository interface.

public class Repository : IRepository where TEntity : BaseEntity

public virtual void Add(TEntity entity)
{
    using (ITransaction __transaction = ___Session.BeginTransaction())
    {
        entity.CreatedDate = DateTime.Now;
        entity.ChangedDate = DateTime.Now;
        ___Session.Save(entity);
        __transaction.Commit();
    }
}
public IList FindAll(Expression<Funcbool>> searchCriteria)
{
    return ParseQuery(___Session)
           .Where(searchCriteria)
           .ToList();           
}
public TEntity GetById(TId id)
{
    return ___Session.Get(id);
}

As mentioned earlier, I have used Linq to NHibernate in my repository classes. Once the base repository is ready, we can start writing some test cases and see how this base repository satisfies our requirements.

[ClassInitialize]
public static void ClassInitialize(TestContext context)
{
    ___sessionFactory = new Configuration()
                       .Configure()
                       .AddAssembly(typeof(BaseEntity<long>).Assembly)
                       .BuildSessionFactory();
}

[TestMethod]
public void can_add_new_customer()
{
    var __customer = new Customer { FirstName = "Rahul", LastName = "P" };
    using (ISession __session = SessionManager.CurrentInstance.Session)
    {
        IRepository<Customer, long> __repository = new Repository<Customer, long>(__session);
        __repository.Add(__customer);
        var __customerFromDb = __repository.First(x => x.FirstName == "Rahul");
        Assert.IsNotNull(__customerFromDb);
        __repository.Remove(__customerFromDb);
    }
}

[TestMethod]
public void can_find_customer_by_search_query()
{
    using (ISession __session = SessionManager.CurrentInstance.Session)
    {
        IRepository<Customer, long> __repository = new Repository<Customer, long>(__session);
        var __customer = __repository.First(x => x.FirstName == "Prajeesh");
        Assert.IsNotNull(__customer);
        Assert.IsTrue(__customer.FirstName == "Prajeesh");
    }
}
Next we’ll work on the CustomerRepository class which inherits from the base repository that we have created here.

NHibernate – Writing unit tests using VSTS (Part 7)


Before writing the first test case against NHibernate, you should make sure that all the required files that are used for NHibernate are available for the test method. For accessing SQL Server 2005 express using NHibernate you should copy the sqlServer dll’s from the Microsoft SQL Server Compact Edition directory in Program files folder to the Lib folder where the NHibernate assemblies are deployed.


Now you need to configure the test environment settings. In the deployment settings of test configuration, make sure that you have mentioned the BuildFolder and the assemblies from the shared location.


Once the deployment options are configured we are good to write our first test case.
[TestClass]
public class NHibernateConfiguration_Fixture
{
    //VSTS framework in 2008 fails to read the NHibernate's configuration on load.
    //To set path for looking the configuration file to the current execution path, you need to manually specify the location.
    //Once the location is set, the RelativeSearchPath property is cleared by calling the ClearPrivatePath() method.

    [AssemblyInitialize]
    public static void AssemblyInitialize(TestContext context)
    {
        AppDomain.CurrentDomain.SetData("APPBASE", System.Environment.CurrentDirectory);
        AppDomain.CurrentDomain.ClearPrivatePath();
    }

    [TestMethod]
    public void can_open_configuration_info_and_create_session()
    {
        var __session = SessionManager.CurrentInstance.Session;
        Assert.IsNotNull(__session);
    }
}
The AssemblyInitilize method set’s the current execution path to look for the configuration file. Once the location is set, we need to clear the Relative search path by making a call to ClearPrivatePath method.
If your test fails double check your test deployment folder and see whether all the assemblies are copied. Next we’ll create our repositories and execute CRUD operations on Customer table.

Wednesday, January 13, 2010

NHibernate – Creating the session factory (Part 6)


In order to create an ISessionFactory instance, we need to create an instance of Configuration during application initialization and use it to set the database access and mapping information. Once configured, this instance is used to create the SessionFactory. As mentioned in the previous post,  session factory is not a lightweight component, so we’ll use a singleton class instance of the SessionFactory and be shared across the instances. I have created a SessionManager class in my sample that creates an instance of the SessionFactory and returns an ISession instance when required.
public class SessionManager
{
    public static SessionManager CurrentInstance
    {
        get
        {
            if (___CurrentInstance == null)
            {
                object __sync = new object();
                lock (__sync)
                    ___CurrentInstance = new SessionManager();
            }
            return ___CurrentInstance;
        }
    }

    public ISession Session
    {
        get
        {
            if (___sessionFactory == null)
            {
                object __sync = new object();
                lock (__sync)
                    ___sessionFactory = new Configuration()
                        .Configure()
                        .AddAssembly(typeof(BaseEntity<long>).Assembly)
                        .BuildSessionFactory();
            }
            return ___sessionFactory.OpenSession();
        }
    }

    private SessionManager() { }

    static SessionManager ___CurrentInstance;
    static ISessionFactory ___sessionFactory;
   
}
Next I’ll show how to configure the system for writing unit tests for the application.

NHibernate – Configuration (Part 5)


Once we have the domain entities and mapping files ready, we need to tell NHibernate about the database server and how to access it. For this we use a file named NHibernate.cfg.xml to configure NHibernate to access a Microsoft SQL Server 2005 express database.
xml version="1.0" encoding="utf-8" ?>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
  <session-factory>
    <property name="connection.driver_class">NHibernate.Driver.SqlClientDriverproperty>
    <property name="connection.connection_string">Server=(local);Initial Catalog=NHibernateSampleDB;User Id=;Password=property>
    <property name="adonet.batch_size">10property>
    <property name="show_sql">falseproperty>
    <property name="dialect">NHibernate.Dialect.MsSql2005Dialectproperty>
    <property name="use_outer_join">trueproperty>
    <property name="command_timeout">60property>
    <property name="query.substitutions">true 1, false 0, yes 'Y', no 'N'property>
    <property name="proxyfactory.factory_class"> NHibernate.ByteCode.LinFu.ProxyFactoryFactory, NHibernate.ByteCode.LinFu property>      
  session-factory>
hibernate-configuration>
This code’s lines specify the following information:
1.       The name of the .NET class implementing the Dialect which enables certain platform dependent features. Despite the ANSI standardization effort, SQL is implemented differently by various databases vendors. So, you must specify a Dialect. NHibernate includes built-in support for most popular SQL databases, and new dialects may be defined easily.
2.       The name of the .NET class implementing the ADO.NET Driver. Note that, since NHibernate 1.2, when using the partial name of a driver which is in the global assembly cache (GAC), you have to add a element in the application configuration file to specify it’s fully qualified name so that NHibernate can successfully load it.
3.       The ConnectionString: the string used to create a database connection as defined by ADO.NET.
NHibenrate allows you to specify the configuration entries in an App.Config/ Web.Config file also. However you may be required to specify the configuration entries under the nhibernate section. I have included the configuration file in a separate project other than the one which has the domain classes. We’ll be using this project for adding our repository classes as well. Another important thing I have done is to mention the output path of all these projects to a common folder.


Next we’ll see how to access this configuration information and create a ISessionFactory instance from the information.

NHibernate – Defining mappings (Part 4)


NHibernate can be configured to run in almost any .NET Application and development environment. To configure NHibenrate the first thing you must do is to create and ISessionFactory instance from the configuration.
Before working on the configuration file, we’ll define our domain entities used in the application. We’ll start by defining the customer entity. The customer entity is a simple POCO class and uses automatic properties.
public class Customer : BaseEntity<long>
{
    public virtual string FirstName { get; set; }
    public virtual string LastName { get; set; }
    public virtual string Address { get; set; }
}
where BaseEntity is the common entity class that every domain entity in our sample inherits from.
public class BaseEntity
{
    public virtual T Id { get; set; }
    public virtual DateTime CreatedDate { get; set; }
    public virtual DateTime ChangedDate { get; set; }
    public virtual byte[] Version { get; set; }
}
The next task is to define the mapping between this class and the corresponding table in the database. This mapping is defined in an xml document, Customer.hbm.xml
xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
                   assembly="BlogsPrajeesh.NHibernate.Domain"
                   namespace="BlogsPrajeesh.NHibernate.Domain">
  <class name="Customer" table="Customers">
    <id name="Id" column="CustomerIntId">
      <generator class="identity" />
    id>
   
   
    <version name="Version" generated="always" unsaved-value="null" type="BinaryBlob">
      <column name="Version" not-null="false" sql-type="timestamp"/>
    version>
    <property name="CreatedDate" type="DateTime" />
    <property name="ChangedDate" type="DateTime" />
    <property name="FirstName" not-null="true" />
    <property name="LastName" not-null="true" />
    <property name="Address" />   
  class>
hibernate-mapping>


Make sure that the mapping file’s build action is defined as ‘Embedded Resource’.  Next we’ll see how to configure NHibernate for the application.