woensdag 31 januari 2007

Meet My Mom

In the past few weeks, I've been making some portraits. Some of them in a studio, others 'on location'.
I will post some of the results here and I'll start with a portrait of my mother.

These photographs are shot in her 'study room'; my mom loves painting and calligraphy (she's pretty good at it) and I wanted to express this in my photographs.


high iso portrait creative mother
Just a pity that she's holding the pen a little bit to high


high iso portrait creative mother2

The photos have been taken with ambient light (I don't like to use flash for location-portraits). I've used a Nikon D200 with a 50mm f/1.8 lens mounted on it. Since there was not too much light available, I've choosen a small aparture number and a high ISO setting. (The EXIF information is available in the picture; you can easily view it using Opanda IEXIF Viewer"). Despite the high ISO setting, I've to admit that I'm pleasantly surprised with the noise levels in these photo's.

zaterdag 20 januari 2007

Lambda expressions in .NET

In C# 3.0, there will be a new feature available: lambda expressions. This new feature was necessary to create the LINQ feature, which will also be introduced in C# 3.0

Today, I came across an interesting article written by Howard Dierking in where he explains what lambda expressions are, and how you can use them.
Very nice and clear article.

Tagged

Seems that I've been tagged by Mike Nichols, so I'm supposed to come up with 5 things you don't know about me; here goes:


  • I've started playing music when I was about 8 or 9 years old. I've played guitar until I was about 16 years old. At that age, I stopped playing music. I didn't wan't to do it anymore. I was supposed to go to music classes each wednesday afternoon, and each saterday morning and I wanted to do other things during that time. :) Sometimes, I regret it though that I didn't continue with that guitar-thing. (I still have my guitar though, and maybe I'll pick it up again in the future)

  • I don't like cheese.
    Well, that's not completely true; I don't eat cheese 'as is', but I do like food that has cheese as an ingredient (pizza, croque monsieur, tiramissu, heck I even like cheese-burgers). I also like Cheetos. Weird huh?

  • I started programming relatively late. I was 17 years old when I wrote my first computer program.

  • I always wanted to become a pilot. Not on airliners, but a jet pilot. :) At age 16, I've sent a letter to the Belgian Air Force to enquire for more information about this. A few days later, I've received an information bundle about it. Unfortunately, I never took part in any of the 'promotions' of the Belgian Air Force. Maybe I was already realistic about my chances: there are only very few positions (about 4 each year) and numerous candidates.
    I haven't lost my interest in jets though; I still like to visit air-shows (although since a plane crashed at the Ostend Airshow in 1997, air-shows in Belgium aren't what they used to be...).
    If I would ever have the chance to be a passenger in a two-seater, I'd certainly do it!

  • I do like karting. Until a few years ago, I used to do it at least once a week. Unfortunately, I'm not able to keep up that frequency right now. I'm already happy if I can go karting once a month.
    I also dream of driving an open-wheel formula race car once (Formula One, Formula Ford, F3000, ... whatever

The 5 persons I'm tagging are: PJ van de Sande, Peter Veentjer, Jelle-Jan Van Veelen, Valentijn and Evan Hoff

woensdag 10 januari 2007

Left- and RightPadding in SQL Server

Although SQL Server contains a few string manipulation functions, there exists no function that allows you to left- or rightpad a string expression.
This is a bit of a pity, since left- and rightpadding is sometimes necessary.

But, no one stops you from creating your own LPAD and RPAD function offcourse; in fact, it is rather very simple. :)
Although SQL Server doesn't provide padding methods out of the box, it doesn't require a lot of work to pad a string.


For instance: suppose you have a variable @number, which contains a number. If you need to leftpad this string with zeroes so that it always contains 8 characters, you simply have to do this:

SELECT RIGHT ('00000000' + @number, 8)

If @number contains '81337', this statement will return '00081337'.

With this knowledge, it is pretty simple to create your own LPAD method. This is the code:

CREATE FUNCTION [dbo].[LPAD] (@string VARCHAR(8000), 
@length INT,
@paddingChar CHAR(1))
AS
BEGIN
RETURN RIGHT (REPLICATE (@paddingChar, @length) + @string, @length)
END

Creating an RPAD function is very similar:

CREATE FUNCTION [dbo].[RPAD] (@string VARCHAR(8000),
@length INT,
@paddingChar CHAR(1))
AS
BEGIN
RETURN LEFT (@string + REPLICATE (@paddingChar, @length), @length)
END

As you might have noticed, REPLICATE is a SQL Server function which repeats a specified characters a number of times. :)

zaterdag 30 december 2006

Shelfari Bookshelf

As a software developer, I reguraly buy (and read) books on software development. I've found a website where you can create your 'virtual bookshelf', and I've decided to create one.


On my virtual shelf, you will mostly find books on software development and photography. Not all of my books are already listed, but I will complete my shelf in the near future.
For some books on my shelf, I've written a little opinion about it. If you want to buy a book that I have on my shelf, you can directly go to the Amazon.com website by clicking on a particular book.
If you want to know my opinion on a particular book for which I haven't supplied an opinion yet, do not hesitate to contact me. :)

woensdag 27 december 2006

VS.NET 2005: XML View of a Typed DataSet

Although I'm not a big proponent of (typed) DataSets ~ I rather use custom business classes ~ , I do have to use them every once in a while.

When I use a typed dataset in VS.NET 2003, I always use 'typed DataSet Annotations'.
This is very easily done in VS.NET 2003: you'll have to switch from DataSet view to XML View, and this can easily be done by the handy buttons that you can see in the lower-left corner:




Clicking on 'XML' would give you the XML view of your typed Dataset; simple as that.

A few days ago, I was working in VS.NET 2005, and I wanted to create a typed DataSet ... I wanted to use the 'annotations' like I was used to do in VS.NET 2003.

I was amazed to find out that those handy XML / DataSet View buttons that exist in VS.NET 2003 are gone in VS.NET 2005.
Apparently, Microsoft doesn't like the idea that developers sometimes want to tweak some settings via code instead of via the properties window ? At least, that's how I'm thinking about it.



After some searching, I've found out that it is still possible to get the XML View of a DataSet in VS.NET 2005, but damn, it is very well hidden.
Here's how you can see the XML definition of the DataSet:


  • Right click on the DataSet file

  • You'll see the following context-menu:


    Select the 'Open With option'

  • The following Dialog Box opens:



    Select the 'XML Editor' option

  • Now, you can see the XML View of the DataSet definition

As you can see, in VS.NET 2005, 3 user interactions are needed in order to go to your destination, instead of just a single click in VS.NET 2003.
Not very productive IMHO.

I wonder why Microsoft has removed those buttons that existed in VS.NET 2003...


zaterdag 9 december 2006

Official owners

Since yesterday, my girlfriend and I are the official and proud owners of this piece of Belgium:




Next step: building a house on it.

vrijdag 1 december 2006

High Key

Yesterday, I've been playing around a bit and wanted to create a high-key picture.
I think the result is quite ok. :)

Apart from some 'levels' adjustements in Photoshop, no other modifications have been made.
I've put the lighters on a plexiglass (hence the reflection), and used two elinchrome strobes to make the picture like it is shown here.

zaterdag 11 november 2006

Nested Transactions in SQL Server

I've been wondering if it would be possible to use 'nested transactions' in SQL Server. To test this, I've set up a little test database and executed a few
T-SQL batches:

USE testdb
BEGIN TRAN
INSERT INTO tblTest (Name) VALUES ('Name1')

BEGIN TRAN
INSERT INTO tblTest (Name) VALUES ('Name2')
COMMIT TRAN

INSERT INTO tblTest (Name) VALUES ('Name3')

COMMIT TRAN

This is trivial, and it works as expected: 3 records have been added to the table. The next batch looks like this:

USE testdb
BEGIN TRAN
INSERT INTO tblTest (Name) VALUES ('Name1')

BEGIN TRAN
INSERT INTO tblTest (Name) VALUES ('Name2')
COMMIT TRAN

INSERT INTO tblTest (Name) VALUES ('Name3')

ROLLBACK TRAN

This is no big deal either: as expected, no records have been added to the table. Up to the next one:

USE testdb
BEGIN TRAN
INSERT INTO tblTest (Name) VALUES ('Name1')

BEGIN TRAN
INSERT INTO tblTest (Name) VALUES ('Name2')
ROLLBACK TRAN

INSERT INTO tblTest (Name) VALUES ('Name3')

COMMIT TRAN

This batch fails with the following error message:

Server: Msg 3902, Level 16, State 1, Line 16

The COMMIT TRANSACTION request has no corresponding BEGIN TRANSACTION.

It turns out that only the last record (Name3) is inserted into the database. That's not what I expected.
Normally, one should expect that Name1 and Name3 are persisted in the database, and only Name2 gets rollbacked.



However, as my collegue Geert pointed out: the BEGIN TRANSACTION statement increments the @@TRANCOUNT Server Variable with 1, and the COMMIT TRANSACTION decrements the @@TRANCOUNT variable with 1.
The ROLLBACK TRAN statement however, decrements the @@TRANCOUNT server variable to 0. That's why the last COMMIT statement gives us the error message: there has been a rollback, and therefore the @@Trancount is set to zero.
Apparently, the ROLLBACK TRANSACTION also rollbacks to the most outer begin transaction, that's why the record 'Name1' is not persisted into the database.

As it turns out, it is not possible to use nested transactions in this way. There is however a way to solve this 'problem':

Savepoints to the rescue

It is possible to use 'savepoints' to solve this problem. As stated in the SQL Server books online:

Savepoints offer a mechanism to roll back portions of transactions.
You use savepoints like this:
BEGIN TRAN
INSERT INTO tblTest (Name) VALUES ('Name1')

SAVE TRANSACTION sp1
INSERT INTO tblTest (Name) VALUES ('Name2')
ROLLBACK TRAN sp1

INSERT INTO tblTest (Name) VALUES ('Name3')

COMMIT TRAN

In this code example, you start a transaction, execute a statement, and save the transaction using the SAVE TRANSACTION sp1 statement.
This statement sets a savepoint with the name 'sp1'. You can then rollback to that savepoint using the ROLLBACK TRAN <savepointname> command.
The result of this batch is as expected: 2 records are inserted into the tblTest table: 'Name1' and 'Name3'

zondag 5 november 2006

Aspect Oriented Programming in .NET

A while ago, there was somebody who asked the question on a programming forum whether it was possible to retrieve the values of the arguments that are passed to a method in .NET. The purpose was to create some kind of a 'logging' system so that he could log which methods have been called, and what values were passed to those methods.
This person had already created a method that retrieved all kinds of information of a certain method, but getting the values of the parameters via reflection was not possible.

The disadvantage of this approach is that your methods are being polluted by this logging method. You always have to add a call to this logging method in your 'business methods'.
For instance:

public void SomeMethod()
{
LogThisMethod (MethodBase.GetCurrentMethod());

// Do the real work here.
}

The call to the LogThisMethod method is not likely a core concern in the application, yet, if you want to log calls to certain methods, you’ll have to write a call to this method in every method that you want to log.
In other words: the logging is a cross-cutting concern because it is an aspect of our program that has nothing to do with the core-problem that is to be solved by our program and it appears in multiple parts of the program.

Luckily, there's a much cleaner approach to solve this problem. Aspect Oriented Programming offers a way to separate cross-cutting concerns like logging in a much cleaner way.
AOP allows you to remove the cross-cutting concerns from your 'business code', and create an 'aspect' for it instead.
This ‘aspect’ will then be weaved into your code at runtime which means that you do not have to call it yourself in the core parts of the application.
In this way, the cross-cutting concerns can be decomposed from the core logic of the application and this will result in more readable and better maintainable software.

In .NET, you can use the Spring.NET framework to apply Aspect Oriented Programming.
In the examples that follow, I’ll be using the Spring.NET framework.

You can solve the logging-problem that I've mentioned earlier using AOP in C# in the following way:

Suppose we have a class 'TestClass' and we want to log every method that is being invoked in this class. Our TestClass looks like this:

public interface ITest
{
void SayHello( string name );
void Shout( string message );
}

public class TestClass : ITest
{
public void Method1( string name )
{
Console.WriteLine ("Hello " + name + " ! ");
}

public void Shout( string message )
{
Console.WriteLine (message + "!!!!!!!");
}
}

These are the steps that have to be taken to create some kind of logging functionality using AOP:


  • Create an Advice that takes care of the logging. An Advice describes a certain ‘procedure’ that must be executed at certain points (joinpoints) in the application. For instance: an Advice can be executed at the entry point of a method.

    If you use Spring.NET, you can create a class which implements the IMethodBeforeAdvice. This will make sure that this Advice is called before a method-call.
    The Advice can look like this:

    public class MethodInvocationLoggingAdvice : IMethodBeforeAdvice
    {

    public void Before( System.Reflection.MethodInfo method,
    object[] args, object target )
    {
    string message = method.Name + " called with ";

    string arguments = string.Empty;

    for( int i = 0; i < args.Length; i++ )
    {
    arguments += args[i] +", ";
    }

    Console.WriteLine (message + arguments.SubString (0, arguments.Length - 2));
    }
    }

    Now, we have separated the logging logic in a separate class.

  • Tell our program to use the Advice
    In our program, we must indicate that our Advice has to be called when we invoke the methods of a certain class.
    Using Spring.NET, we can do this with only 3 lines of code:
    static void Main()
    {
    ProxyFactory f = new ProxyFactory (new TestClass());

    f.AddAdvice (new MethodInvocationLoggingAdvice());

    ITest t = (ITest)f.GetProxy();

    t.SayHello ("Frederik");

    t.Shout ("Watch out");
    }

    The beautiful thing is, that we've kept our 'business methods' clean and every time we invoke a method, the logging functionality is called. If we extend our TestClass with a couple of new methods, we do not have to worry about this logging functionality, since those new methods will also call our MethodInvocationLoggingAdvice as well.

But, what if you only want to log invocations of certain methods, instead of logging every method call? This can also be done rather easily by defining a PointCut. Everytime the pointcut is reached, our Advice will be executed.
.NET attributes provide a great way to define PointCuts.

Building on the previous example, we can extend our code so that the MethodInvocationLoggingAdvice is only called when a method is decorated with a specific Attribute. For instance: only invocations of methods that have the 'Log' attribute, must be logged.
To do this, we must first create this Log attribute:

[AttributeUsage(AttributeTargets.Method)]
public class LogAttribute : Attribute
{
}

We can now change the TestClass to indicate that only method-calls to the Shout method should be logged:
public class TestClass : ITest
{
public void Method1( string name )
{
Console.WriteLine ("Hello " + name + " ! ");
}

[Log]
public void Shout( string message )
{
Console.WriteLine (message + "!!!!!!!");
}
}

All what's left to do, is to make a change to the code that will be responsible of weaving the advice into our code. We must now indicate that our Advice should only be executed on methods that have the Log attribute.
static void Main()
{
ProxyFactory f = new ProxyFactory (new TestClass());

f.AddAdvisor (new DefaultPointCutAdvisor (
new AttributeMatchMethodPointcut (typeof(LogAttribute),
new MethodInvocationLoggingAdvice()));

ITest t = (ITest)f.GetProxy();

t.SayHello ("Frederik");

t.Shout ("Watch out");
}

When you execute this program, you'll see that only the method-call to 'Shout' is being logged.