July, 2010 Archives
Jul
Merge assemblies with ILMerge
by Mikael Lundin in Programming
ILMerge is a tool for merging assemblies together, which is very useful for easy deployments. Instead of deploying 10 dlls you can deploy one. When distributing applications out to customers you really want to make the application as simple as possible, and the most simple application is one that consist of only one exe.
ILMerge in .NET 4
I had some problems using ILMerge with .NET 4 dlls, but managed to get around my problems with some extra parameters. Here’s how you merge dlls into a single DLL using ILMerge.
ilmerge.exe /lib:"C:\Windows\Microsoft.NET\Framework\v4.0.30319" /lib:"C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\PublicAssemblies" /t:dll /targetplatform:v4,C:\Windows\Microsoft.NET\Framework\v4.0.30319 /out:MyApplication.merged.dll MyApplication.dll ReferenceAssembly1.dll ReferenceAssembly2.dll ReferenceAssembly3.dll
It’s easy to merge dlls into an exe, just by changing target type. Use your original exe as the first argument after option parameters.
ilmerge.exe /lib:"C:\Windows\Microsoft.NET\Framework\v4.0.30319" /lib:"C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\PublicAssemblies" /t:exe /targetplatform:v4,C:\Windows\Microsoft.NET\Framework\v4.0.30319 /out:MyApplication.merged.exe MyApplication.exe ReferenceAssembly1.dll ReferenceAssembly2.dll ReferenceAssembly3.dll
In your build process
You can easily apply this in your build process.
- Copy ilmerge.exe to somewhere in your project path. I placed mine in a folder called External Tools.
- Right click your main project in Visual Studio and select Properties / Build Events.

- I use the following to merge assemblies for TogglChart into one dll.
"$(SolutionDir)External Tools\ilmerge" /lib:"C:\Windows\Microsoft.NET\Framework\v4.0.30319" /lib:"D:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\PublicAssemblies" /t:dll /targetplatform:v4,C:\Windows\Microsoft.NET\Framework\v4.0.30319 /out:"$(TargetDir)$(SolutionName).merged.dll" "$(TargetDir)TogglChart.Lib.dll" "$(TargetDir)Newtonsoft.Json.dll" "$(TargetDir)ZedGraph.dll"
Jul
TogglChart – a Toggl charting solution
by Mikael Lundin in Programming, Technicalities
I’ve studied before how to connect to the Toggl API both here and here. Toggl is a tool for easily tracking time put in a project. This is necessary for billing customers, but also useful for tracking your own effort to a project.
I’ve written a command line tool that will extract data from Toggl API and create a chart that will show amount of hours spent per week. A chart can look like this.
All you need to do, is to call the executable with your API Token as required argument.
TogglChart.exe -apiToken=ec3223d0919b45ec2267826fc0954db0
There are some posibilities to customize the output. Here’s the full usage for this command line tool.
--apiToken=VALUE Your API token from Toggl. Easily find in "My
settings" https://www.toggl.com/user/edit
--imageWidth=VALUE Width of the result chart in pixels (image will
scale to fit width)
--imageHeight=VALUE Height of the result chart in pixels (image will
scale to fit height)
--imageTitle=VALUE The main title of the chart that will be shown
at the top.
--outputFile=VALUE Path and filename to the output file. Example:
toggle.jpg
--imageFormat=VALUE Filetype of the result image. Legal values are
jpg, png, bmp and gif
--weeks=VALUE Number of weeks backwards that tasks should be
fetched from Toggl.
--projectName=VALUE The name of the project in Toggl. This is useful
to specify when you have several different
projects that you register time on and only want
to create chart for one of them. If you don't
specify project name, chart will be created from
all projects combined.
--dynamic If you set this value to true, empty weeks at
beginning of the period will be removed.
--help, -h, -? Displays this message.
MsBuild Task
I’ve also included an MSBuild task. Instead of using the TogglChart.exe directly you can call the MSBuild task inside the TogglChart.dll.
<!-- TOGGLCHART --> <UsingTask TaskName="TogglChart.MsBuild.TogglChart" AssemblyFile="$(MSBuildProjectDirectory)\ExternalTools\TogglChart.dll" /> <Target Name="TogglChart"> <TogglChart ApiToken="ec3223d0919b45ec2259296fc0954db0" ImageWidth="320" ImageHeight="240" ImageTitle="Time spent on Hippo" OutputFile="$(ArtifactDirectory)\togglchart.jpg" ImageFormat="jpg" Weeks="10" ProjectName="Hippo" Dynamic="true" /> </Target>
Both TogglChart.exe and TogglChart.dll are stand-alone. You do not need the DLL for the EXE to run, nor the other way around.
Download
License: You are free to use and distribute this application.
Jul
Introduction to NHibernate
by Mikael Lundin in Programming
I held this introduction to NHibernate yesterday and thought it might be nice to share this with you. It is just a basic NHibernate application without any fancy schmancy, to familiarize yourself with the concepts.
Download and install the Northwind database
This example builds upon the Northwind database. Please download and install it from here. Once installed you need to find the database install SQL script that should be located in C:\SQL Server 2000 Sample Databases\instnwnd.sql and run it on a database that is available to you.
Create a domain model
Next thing you create a new Visual Studio console project/solution. This will make it easy for you to run and debug your mappings later.
As you can see I’ve created a namespace for our OR-mappings and the domain model. Please download NHibernate and reference it to your project. I’ve used version 2.1.2.GA in my solution. Don’t forget to include binaries for lazy loading. I’m using Castle in this example.
We keep the domain simple for this example. Here’s what the code looks like for these two domain classes. An important aspect here is to keep the properties virtual.
namespace NHibernateExample.Model
{
public class Product
{
public Product()
{
}
public Product(string name, double price)
{
Name = name;
Price = price;
}
public virtual int ID { get; set; }
public virtual string Name { get; set; }
public virtual double Price { get; set; }
public virtual Category Category { get; set; }
}
public class Category
{
public virtual int ID { get; set; }
public virtual string Name { get; set; }
public virtual string Description { get; set; }
}
}
The object relational mapping
You map the database tables to your entity object by writing hbm.xml-mapping files. There are nicer ways to do the mapping through code, but I will go through the most common way of mappings here instead.
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="NHibernateExample" namespace="NHibernateExample.Model">
<class name="NHibernateExample.Model.Product, NHibernateExample" table="Products">
<id name="ID" column="ProductID">
<generator class="identity" />
</id>
<property name="Name" column="ProductName" />
<property name="Price" column="UnitPrice" />
<many-to-one name="Category" class="NHibernateExample.Model.Category, NHibernateExample" column="CategoryID" />
</class>
</hibernate-mapping>
Notice that the ID is specified to be generated as “identity”. This means that ID is an identity column in the table, and that the SQL server will generate the value for us on insert.
You can also see how Product is related to Category with a many-to-one relationship. We specify the foreign key column name in the column attribute.
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="NHibernateExample" namespace="NHibernateExample.Model">
<class name="NHibernateExample.Model.Category, NHibernateExample" table="Categories">
<id name="ID" column="CategoryID">
<generator class="identity" />
</id>
<property name="Name" column="CategoryName" />
<property name="Description" />
</class>
</hibernate-mapping>
Description does not need to specify column name, because it is the same as property name. This is one of the defaults of NHibernate.
You’ll have to mark the hbm.xml-files as Embedded Resources for NHibernate to find them.
NHibernate configuration
The configuration for NHibernate specifies what database provider to use, SQL dialect and connection string to the database. If you want NHibernate to be verbose about it’s SQL you can set show_sql to true.
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
<session-factory>
<property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
<property name="dialect">NHibernate.Dialect.MsSql2000Dialect</property>
<property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>
<property name="connection.connection_string">Data Source=(local);Initial Catalog=Northwind;Integrated Security=SSPI</property>
<property name='proxyfactory.factory_class'>NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle</property>
<property name="show_sql">true</property>
</session-factory>
</hibernate-configuration>
This xml should be placed in a hibernate.cfg.xml that should be placed in the root of your project. Make sure to mark it as Copy to Output Directory: Copy Always. This file must be present in the output bin directory, unless you choose to specify the path while building the SessionFactory.
Session Management
If you’re writing a web application, you might want to consider using one session for each and every request. You can read more about how to accomplish that here and here. In this simple example we will open one session for every database call. That should not be a problem since ISession is considered to be a lightweight object, in contrary to ISessionFactory that should be built only once per application.
public class SessionManager
{
private ISessionFactory globalSessionFactory;
private static readonly object PadLock = new object();
private static SessionManager instance;
public static SessionManager Current
{
get
{
lock (PadLock)
{
return instance ?? (instance = new SessionManager());
}
}
}
public ISession OpenSession()
{
if (globalSessionFactory == null)
{
globalSessionFactory = CreateSessionFactory();
}
return globalSessionFactory.OpenSession();
}
private ISessionFactory CreateSessionFactory()
{
return new Configuration()
.Configure()
.AddAssembly(typeof(SessionManager).Assembly)
.BuildSessionFactory();
}
private SessionManager()
{
}
}
In CreateSessionFactory we do Configure() to load the hibernate.cfg.xml file, and AddAssembly will search for and load our Product.hbm.xml and Category.hbm.xml mapping files.
RepositoryBase pattern
Now when we easily can get an instance of ISession from our SessionManager, we can figure out how to do simple CRUD operations on our entities. For this we create a base class for our ProductRepository and CategoryRepository to derive from later.
public abstract class RepositoryBase<TEntity>
where TEntity : class
{
protected SessionManager SessionManager;
public RepositoryBase(SessionManager sessionManager)
{
SessionManager = sessionManager;
}
public TEntity GetById(object id)
{
using (var session = SessionManager.OpenSession())
{
return session.Get<TEntity>(id);
}
}
public void Insert(TEntity TEntity)
{
using (var session = SessionManager.OpenSession())
using (var transaction = session.BeginTransaction())
{
session.Save(TEntity);
transaction.Commit();
}
}
public void Update(TEntity TEntity)
{
using (var session = SessionManager.OpenSession())
using (var transaction = session.BeginTransaction())
{
session.Update(TEntity);
transaction.Commit();
}
}
public void Delete(TEntity TEntity)
{
using (var session = SessionManager.OpenSession())
using (var transaction = session.BeginTransaction())
{
session.Delete(TEntity);
transaction.Commit();
}
}
}
We need transactions for all operations that changes the datasource. That’s because we can’t know if our Insert operation will have to insert data into more than one table, and if it conflicts somewhere along the way we would like the operation to be atomic, and rollback to the state before we started our insert.
Here’s how we implement ProductRepository and CategoryRepository now.
public class ProductRepository : RepositoryBase<Product>
{
public ProductRepository(SessionManager sessionManager)
: base(sessionManager)
{
}
public IEnumerable<Product> GetByCategory(Category category)
{
using (var session = sessionManager.OpenSession())
{
return session.CreateQuery("FROM Product as product WHERE product.Category = :category")
.SetEntity("category", category)
.List<Product>();
}
}
}
public class CategoryRepository : RepositoryBase<Category>
{
public CategoryRepository(SessionManager sessionManager)
: base(sessionManager)
{
}
}
I’ve also extended the ProductRepository with a database call to get all Products within a specfied category. A query that is specific for the Product entity and not part of the base repository.
An example application
Here’s an example of how we can use the framework.
public class Program
{
public static void Main(string[] args)
{
var beverages = new CategoryRepository(SessionManager.Current).GetById(1);
var product = new Product("Juice", 12d) { Category = beverages };
var repository = new ProductRepository(SessionManager.Current);
repository.Insert(product);
product.Price = 15d;
repository.Update(product);
repository.Delete(product);
foreach (var beverage in repository.GetByCategory(beverages))
{
Console.WriteLine("{0}, {1} {2:c}", beverage.ID, beverage.Name, beverage.Price);
}
Console.ReadLine();
}
}
The whole example can be downloaded from here. (Visual Studio 2008 solution)





