Tuesday, February 28, 2006

The sheer time involved boggles me

Check this out: http://preview.local.live.com/

basically allows you to drive down streets in Seattle or San Fran.

What really amazed me was turning to the side and seeing a picture of a store front. I have no idea how all of these pictures could have been taken and assembled.

I am waiting for a real time driving simulator now so that I can get around a city before I arrive there (sorry I am a dork).

Monday, February 27, 2006

Code inventor or serial killer

Take this quiz to see if you can spot the code inventor or the serial killer. I got 9/10 which is pretty freaky.

Friday, February 24, 2006

Side by Side versioning is not so with COM+

Today I discovered that when you try to install a com+ (or enterprise service if you want) componenet written in 1.1 of the framework on a system that has 2.0 also installed that you can not install some componenets. I have no idea why or how to fix it besides uninstalling 2.0 then installing your componenet. Then reinstall 2.0 after if you need it.

...weird!

Unit testing and the database

I have been playing with unit testing for over a year now and really see the value in it. Most of the time you build your tests along with (or before in the case of test driven development) your code. But I have even found it valuable to write tests for code I have already written in the past if I am going to have to make a change. I usually only write a test for the method I am about to change, make my change and then see if my test still passes.

One of the things that I hate is how many articles recommend to mock the database so that no database calls are made. The reason for this is that database interaction is a performance killer. Second of all it loads the database with tons of repeated test data (unless you perform a cleanup in your test case that is).

I feel that it is invaluable to have your tests hit the database. I have had cases where all of the business rules pass but when it hits the database an exception is thrown. If I had mocked the database I would not know about this. Granted it is slow to do it this way but I would rather be slow than buggy.

As far as loading the database with repeated test data there are a couple of ways around it. The first is to have every test clean its footprint up which is a big pain. The second way is to enlist the test in a distributed transaction, running the test, and then rolling back the transaction. The way I do this is have a base class that all of my tests inherit from and then have the enlist / rollback in the setup and teardown methods respectively. Here is my standard TestBase class

1 Imports NUnit.Framework

2 Imports System.EnterpriseServices

3

4 _

5 Public Class TestBase

6

7 _

8 Public Sub Setup()

9 ' Enter a new transaction without inheriting from ServicedComponent

10 Console.WriteLine("Attempting to enter a transactional context...")

11 Dim config As New ServiceConfig

12 config.Transaction = TransactionOption.RequiresNew

13 ServiceDomain.Enter(config)

14 Console.WriteLine("Attempt suceeded!")

15 End Sub

16

17 _

18 Public Sub Teardown()

19 Console.WriteLine("Attempting to Leave transactional context...")

20 If (ContextUtil.IsInTransaction) Then

21

22 ContextUtil.SetAbort()

23 End If

24 ServiceDomain.Leave()

25 Console.WriteLine("Left context!")

26 End Sub

27 End Class

28



The ServiceDomain class is something most people don't know about and is quite handy to ccreate a localized transaction. You can see that it creates a config that requires a new transaction and then calls ServiceDomain.Enter(config). This changes the context of the application to change and participate in a transaction.

In our tear down we check if we are in a transaction with ContextUtil and then Abort the transaction if we are in it. This will cause all of our interactions with anything that can use DTC to rollback.

So now you can test your database and not worry about garbage data all over your system. I like this as when I put an applicaiton into production I can run my tests against it and double check that no enviromental errors occured without introducing garbage data.

Wednesday, February 22, 2006

Marking a method as obsolete

I am currently working on an enterprise system that already has several consumers. There are several methods that have been replaced by newer methods and I want the clients to stop consuming the old ones. Unfortunately if I just tell them to use the new ones they wont, and when I release a new version and it breaks they will complain. I found a neat way to deprecate a method

1 _

2 Public Function oldWay() As Boolean

3

4 End Function



now whenever a consumer compiles they will get a compiler warning stating that the method has been replaced by method newWay()

You can also make the compile give a warning instead of an error by using one of the overloads

1 _


By setting the last parameter to true the compiler will show an error instead of a warning.

(the first example I posted might actually show an error instead of a warning. I will post more once I experiment with it)

XSTL / XML and the information bar

I am trying out XSLT w/ XML for a project I am doing. Basically the website has a page for each staff memeber with a bio, phone, website, email, photo, etc. The client does not want to pay for a database solution which I would normally do so I decided to try XSLT (If you have no idea what XSLT is you should check out the quick tutorial at www.w3schools.com). Well found a few snags but the one that bugs me the most is the information bar in internet explorer that says it "blocked content that may harm my computer". After some playing and diggiing I found that because it is on my local computer that it is running in the local security zone where it can do damage. If I upload the page I get no warnings because IE puts it into the "Internet Zone" where the active content is blocked by default. To fix this you can place a Mark Of The Web (MOTW) into the xml and xslt document to force a local document to run in the Internet Zone.

Here is a sample:
my xsl file:



...


my xml file:





....



The comment that says "saved from url" is the MOTW. the first part is the string length of the url (26) and the second part is the url of the file.

As far as I can tell I can put any url in there even if that is not where the file is actually hosted.

Tuesday, February 21, 2006

State management technique

One thing that I hate is how most developers access session or cookies like this

1 Dim firstname As String = Session("firstName")


and then 100 times in the application you have the hard code of firstName. About a year ago Tim showed me this very simple and effective way to centralize this. I don't know if there is a name for this technique but I sure love it:

1 Public Class StateManager

2 Public Shared Property FirstName() As String

3 Get

4 Return StateEngine("fistName")

5 End Get

6 Set(ByVal Value As String)

7 StateEngine("FirstName") = Value

8 End Set

9 End Property

10

11 Private Shared Property StateEngine(ByVal key As String)

12 Get

13 Return System.Web.HttpContext.Current.Session(key)

14 End Get

15 Set(ByVal Value As Object)

16 System.Web.HttpContext.Current.Session(key) = Value

17 End Set

18 End Property

19 End Class


now whenever you need to get/set something from state all you have to do is:

1 Dim firstname As String = StateManager.FirstName



This also alows you to change your state management solution very quickly. If you wanted to move away from session to cookies you would only have to change the implementation in the StateEngine method.

Patterns: Gateway Pattern

One of my favorite patterns is the gateway pattern. Basically it is setting up one class that all requests for a certain action run through. The time I use this the most often is when accessing an external service.

For example lets say that I use an external service multiple times in an application (in this case I am accessing over a webservice but it could be com, remoting, a database, almost anything)

In my example I have an external web service that I use to find the customers ID via a phone number.

3 Public Class Payment

4 Public Function CreatePayment(ByVal customerPhoneNumber As String, ByVal amount As Decimal)

5 Dim wsPerson As New com.example.Person

6 Dim personId As Integer = wsPerson.GetId(customerPhoneNumber)

7 Dim paymentId As Integer = Data.CreatePayment(personId, amount)

8 Return paymentId

9 End Function

10 End Class



12 Public Class Refund

13 Public Function CreateRefund(ByVal customerPhoneNumber As String, ByVal amount As Decimal, ByVal paymentId As Integer) As Integer

14 Dim wsPerson As New com.example.Person

15 Dim personId As Integer = wsPerson.GetId(customerPhoneNumber)

16 Dim refundId As Integer = Data.CreateRefund(personId, paymentId, amount)

17 Return refundId

18 End Function

19 End Class


Now if we ever need to change the service we are using or how it is implemented (i.e. the web service gets changed to remoting or the method to get a person changes) we need to change it all over our application. So to fix this we create a gateway class that pipes all calls to the remote service through it:

2 Public Class PersonGateway

3 Public Shared Function GetPersonId(ByVal customerPhoneNumber As String) As Integer

4 Dim wsPerson As New com.example.Person

5 Return wsPerson.GetId(customerPhoneNumber)

6 End Function

7 End Class



We then change our payment and refund classes to use the new gateway:

10 Public Class Payment

11 Public Function CreatePayment(ByVal customerPhoneNumber As String, ByVal amount As Decimal)

12 Dim personId As Integer = PersonGateway.GetPersonId(customerPhoneNumber)

13 Dim paymentId As Integer = Data.CreatePayment(personId, amount)

14 Return paymentId

15 End Function

16 End Class

17

18 Public Class Refund

19 Public Function CreateRefund(ByVal customerPhoneNumber As String, ByVal amount As Decimal, ByVal paymentId As Integer) As Integer

20 Dim personId As Integer = PersonGateway.GetPersonId(customerPhoneNumber)

21 Dim refundId As Integer = Data.CreateRefund(personId, paymentId, amount)

22 Return refundId

23 End Function

24 End Class


Now we have all calls to the external service in one place. Now we can make changes easily. For example say that the develpers of the Person web service change the method signature to require you to supply a username and password to call the method to prevent outside applications for getting customers information we only have one place to change it:

2 Public Class PersonGateway

3 Public Shared Function GetPersonId(ByVal customerPhoneNumber As String) As Integer

4 Dim wsPerson As New com.example.Person

5 Return wsPerson.GetId(customerPhoneNumber, "Kudos", "QWERTY")

6 End Function

7 End Class


This also could allow us a central point to validate the customerPhoneNumber if we wanted as well. By using this methodology it is also easier to create a dummy webservice for testing purposes that allows the application to be debugged without having to rely on an external webservice.

Classifying Programmers

I was recently asked in an interview how I classify programmers. I found it interesting as there is no set classification of programmers. Here is what I came up with:

Junior Programmer
-Programmer has difficulties with the language itself (e.g. declaring objects, using properties, sizing of arrays)
-Programmer is not familiar with a lot of the builtin functions/objects in the language (e.g.
-Programmer is not comfterable / aware of OOP.
-Programmer usually has no understanding of interfaces
-Programmer usually can not forsee how to implement a solution and needs to be instructed on the steps to take to acheive the end result.

Intermediate Programmer
-Programmer is comfterable with the programming language
-Programmer is not familiar with more advanced items of the language (e.g. threading, remoting, com)
-Programmer is fairly familiar with object orientated programming concepts and is comfterable in using them but still runs into problems with some aspects of it
-Programmer knows how to implement interfaces but sees no reason to create them for their own code.
-Programmer runs into problems that they could not forsee which might require backtracking of code / workarounds.

Senior Programmer
-Programmer is proficient in the programming language
-Programmer has a good understanding of OOP, threading, async programming, and can pick up any new technology (e.g. remoting) and learn it quickly by building on knowledge of similar technologies / underlying principals
-Programmer should be capable of forseeing the strengths / weaknesses of taking a certain route.


Well that is all that I have come up with so far. Please comment on this and let me know your opinion!

Monday, February 20, 2006

Design Patterns: Factory Pattern

I have always heard of the factory pattern and it is one of the more common patterns out there. I just never really knew why / when to use it until recently. There are serveral compelling reasons to use the factory pattern.

What is a factory?
Simply put factories are classes / methods that build objects. Here is a simple example of a factory that creates a car:

public function CreateCar(color as string, model as string, year as integer, isHatchback as boolean) as Vehicle
dim car as new Vehicle()
car.color=color
car.model=model
car.year=year

if isHatchback then
car.NumberOfDoors = 3
else
car.NumberOfDoors = 4
end if

return car
end function

we could then add another factory that creates a truck

public function CreateTruck(color as string, model as string, year as integer) as Vehicle
dim truck as new Vehicle()
truck.color=color
truck.model=model
truck.year=year
truck.numberOfDoors = 2
return truck
end function



What I like to do is put the factory methods directly into the object I am creating (in this case Vehicle). I then make the constructor private to force users to call the Create____ method. i.e.:

public class Vehicle()
dim color as string
dim model as string
dim year as integer
dim numberOfDoors as integer
dim fuel as string

private sub new()
engine = "gas"
end sub

public shared function CreateCar(color as string, model as string, year as integer, isHatchback as boolean) as Vehicle
dim car as new Vehicle()
car.color=color
car.model=model
car.year=year

if isHatchback then
car.NumberOfDoors = 3
else
car.NumberOfDoors = 4
end if

return car
end function

public shared function CreateTruck(color as string, model as string, year as integer) as Vehicle
dim truck as new Vehicle()
truck.color=color
truck.model=model
truck.year=year
truck.numberOfDoors = 2
return truck
end function

end class

Now if you are anything like me you would be thinking why not just use the new constructor in vehicle to do this? The answer is yes we could but no we should not.

The main reason I use a factory is clarity. You can only name a constructor "new". which is not very descriptive. If we used the new constructor the signature woud look like this:
public sub new (color as string, model as string, year as integer, isHatchback as boolean)
public sub new (color as string, model as string, year as integer)

As a developer not familiar with the code I might assume I can create a car by calling the second method only to be supprised that it comes back as a car with 2 doors which is not what I desired. Where as if it was done through the factory method I know just by the name of the method that I should call CreateCar() to create a car and CreateTruck() to create a truck.

The other place a factory can be usefull is with inheritance chains as the new() constructors on objects do not get inherited but the factory methods will.

It is quick to see how powerfull this technique can be and where it can be used. Be warned though that most developers expect methods to have a new constructor on objects. This is why it is gennerally a common practice to prefix factory methods with the word Create. i.e. sqlConnection.CreateCommand() returns a command object associated to the command.

Wednesday, February 15, 2006

Getting the current Method

I have an application that logs information when each method runs:

1 Public Function GetRefundsByID(ByVal id As Integer)

2 'implementation

3

4 LogMessage(String.Format("GetRefundsByID found {0} records", count))

5 End Function


I dont really like this as I have now hardcoded the name of the function into each method which really sucks when I rename a method.

I managed to figure a way to get the current method name via reflection though (note that reflection can adversley affect performance)

1 Private Function GetCurrentMethodName() As String

2 Dim stackTrace As New StackTrace 'the stack trace

3 Dim stackFrame As StackFrame 'one frame of the stack i.e. the last calling method

4 Dim methodBase As methodBase 'the method info

5

6 stackFrame = stackTrace.GetFrame(1) 'get the frame that happened just before this method

7 methodBase = stackFrame.GetMethod() 'get the method info from that frame

8

9 Return methodBase.Name

10 End Function


Now that code is a little ugly so here it is refactored:

1 Public Function GetcurrentMethodName()

2 Return New StackTrace().GetFrame(1).GetMethod().Name

3 End Function


Or if you want to show the parameter signature you can use this:

1 Private Function GetCurrentMethodName() As String

2 Dim methodBase As System.Reflection.MethodBase

3 Dim sb As New System.Text.StringBuilder

4

5 methodBase = New StackTrace().GetFrame(1).GetMethod()

6

7 sb.AppendFormat("{0} (", methodBase.Name)

8 For Each param As System.Reflection.ParameterInfo In methodBase.GetParameters()

9 sb.AppendFormat(param.Name & " as " & param.ParameterType().Name)

10 Next

11 sb.AppendFormat(")")

12

13 Return sb.ToString

14 End Function