vrijdag 29 augustus 2008

Google maps support for your asp.net site

I used the club starter kit as a base website template for my soccer team.  It has a location feature where you can put the locations of certain important events (where our next game is, where do we meet up front, where are we having drinks afterwards, etc...).  I though it would be nice to add support for Google maps so we can see where we'll have to play and give my teammates directions.  This way I would already resolve the lame excuses that they usually have for being late.

At first I just looked at the Google website.  Where else would you check how to integrate Google maps in your web app?  I found an entire JavaScript api ready for use so I started hacking away.  Now I must admit JavaScript is not my favorite language, I can manage but that's about it.  Since I believe there will be other developers just like me, someone must have written server controls for it.  And yes there is one available Googlemaps.subgurim (Free for non commercial use)

Just drag an drop the map control into your page, size it decently and put code to position the map in the page_load event handler.  The website contains many useful and simple samples so I won't bore you with implementation details.  You can see the map in action on my soccer's team (gilsboys) website (click the location list hyperlink for more locations).  But I have to warn you if you decide to explore more of the site is in Dutch and my team is not famous for the way we play soccer but more for the drinks and parties afterwards.  I guess it's my way of apologizing already for the pictures that are already available :-)

Check with you later !

dinsdag 26 augustus 2008

Template your way into the hearts of your users !

This week we discussed our communication strategy at work.  As already told previously we are writing a security service which involves creating users, adding and removing permissions and so on...  Any of these actions can be performed by various actors (the user himself, an administrator, some batch job, ....) and thus the user must be notified about any change!  Of course requirements are that the business should be able to change the emails, so hard coding them is out of the question (as always :-).

I had a look at a couple of template engines this weekend to solve the problem.  Since I used Stringtemplate before I decided to go along with that one.  The beauty of a template engine is that you can pass in an object graph and let the template figure out what to write and more importantly how to write it.  First task was to make a simple email template that could be sent to the user:

1 group TemplateEmail; 2 3 Email(person, action) ::= << 4 5 \<html\> 6 \<body\> 7 Dear <person.name>, 8 \<br\> 9 \<br\> 10 11 You receive this email because the following action \<b\> "<action.Name>" \</b\> has occurred. 12 \<br\> 13 \<br\> 14 15 This leads to changes in the permissions you have on our applications. 16 \<br\> 17 18 Please logon into our application to validate your permissions. 19 20 \<br\> 21 \<br\> 22 \<br\> 23 Sincerly, 24 Patrick 25 \</html\> 26 \</body\> 27 >>

Done, this template creates a personal email with a header including the user's name and a subject containing the action that has occurred.  Please not that the html syntax is entirely escaped because the < and > are used to refer to parameters and other templates.  According to the documentation you should be able to use $ as well, but in my template these templates were never replaced.  Is it because the dollar is that low?  :-)). 

The two templates that need replacing are <person.name> and <action.name>, the engine will try to find a property name on both of these objects (person and action), which need to be handed to the template engine.  (If it cannot find this, the templates results in an empty string).  Next we need to convert this template into a email with all values filled in, the following code does just about that:

1 var group = new StringTemplateGroup(new StreamReader("templates\\TemplateEmail.st")); 2 var template = group.GetInstanceOf("Email"); 3 4 template .SetAttribute("person", person); 5 template .SetAttribute("action", action); 6 7 var emailBody = query.ToString();

Again, piece of cake, if you put the result of the toString() into your email body you have nicely formatted email.  How did this work?  The first line reads the file from the disk in which the templates are stored.  You get a group of templates as result, you then ask it for your named template.  If you require attributes you can set them here by using the SetAttribute methods.  Finally let the template engine do its work by calling the toString() on it.

All right, seems that basic templating is easy, let's switch to the next gear and divide our template into several little reusable templates.  After all we will want to send different mails based on what action has been performed, the type of user who has performed the action, ....  So let us create some templates for a mail header, mail subject and mail footer:

1 WriteMailHeader(person) ::= << 2 3 \<html\> 4 \<body\> 5 \<div\> 6 Dear <person.name>, 7 \</div\> 8 \<br\> 9 \<br\> 10 >> 11 12 WriteMailAction(action) ::= << 13 14 You receive this email because the following action \<b\> "<action.Name>" \</b\> has occurred. 15 \<br\> 16 \<br\> 17 >> 18 19 WriteEmailFooter() ::= << 20 \<br\> 21 \<br\> 22 \<br\> 23 Sincerly, 24 Patrick 25 \</html\> 26 \</body\> 27 >>

As you can see all multi line templates start with the template name followed by the argument list.  The ::= << sign means the templates starts here and ends with the >> sign.  Our mail template can now be rewritten as follows:

1 group TemplateEmail; 2 3 Email(person, action) ::= << 4 <WriteEmailHeader(person)> 5 <WriteEmailAction(action)> 6 7 This leads to changes in the permissions you have on our applications. 8 \<br\> 9 10 Please logon into our application to validate your permissions. 11 <WriteEmailEnding()> 12 >> 13

The following step is to make our mail more useful by providing extra information.  Lets assume that our Person has a property AuthorizationSet which holds two collections (one for the applications you are authorized to use and one for the functionalities you can execute).  Our template can now read these properties and act upon these values.  So let's add the applications and functionalities you are authorized for in the mail template.

1 WriteApplicationInformation(person) ::= << 2 You have access to the following applications: 3 \<ul\> 4 <person.AuthorizationSet.Applications:{application|<WriteApplicationInformationLine(application)>}; separator="\n"> 5 \</ul\> 6 >> 7 8 WriteApplicationInformationLine(application) ::= << 9 \<li\> <application.Name> of type <application.Type> valid from <application.StartDate> till <application.EndDate> \</li\> 10 >> 11 12 WriteFunctionalityInformation(person) ::= << 13 You have access to the following functionalities: 14 \<ul\> 15 <person.AuthorizationSet.Functionalities:{functionality|<WriteFunctionalityInformationLine(functionality)>}; separator="\n"> 16 \</ul\> 17 >> 18 19 WriteFunctionalityInformationLine(functionality) ::= << 20 \<li\> <functionality.Name> with code <functionality.Code> valid from <functionality.StartDate> till <functionality.EndDate> \</li\> 21 >> 22 23

And you simply call these templates with the following 2 lines in your email template:

<WriteApplicationInformation(person)> <WriteFunctionalityInformation(person)>

Let's go a little bit deeper in the previous templates we've seen, shall we!  We have created 4 sub templates, two for application permissions (WriteApplicationInformation and WriteApplicationInformationLine) and two for functionality permissions (WriteFunctionalityInformation and WriteFunctionalityInformationLine).  The main template calls the line template for each item.  This is achieved by the following syntax: < property : { subtemplate }; separator = "\n">,.  This means that for each property (if it is an array, otherwise it will be called only once) the subtemplate is called, the "\n" character will be used in the template between every iterated call.  The subtemplate has the following pattern { parameter | <template(parameter)>}.  First you name the value for each iterated object, then you specify what other named template to call (or use an inline template).

Finally I would like to add extra information on the items depending on the value we have in the permission sets.  Every permission has a start date and an end date.  These are shown as well, but now when a permission has an end date set to sometime far in the future, it doesn't really add any extra value.  On top of that it looks unprofessional too, so let's us vary the template based on wether we have a permission that is open ended.  First add an extra property in your permission class IsOpenEnded that returns true/false based on the EndDate == DateTime.MaxValue.  Then make an if structure in your template depending on this property.  If we have an open end, we simply make do not display the end date, but show a slightly different text.

1 WriteApplicationInformationLine(application) ::= << 2 \<li\> 3 <application.Name> of type <application.Type> 4 <if(application.IsOpenEnded)> 5 valid from <application.StartDate> till piggs can fly 6 <else> 7 valid from <application.StartDate> till <application.EndDate> 8 <endif> 9 \</li\> 10 >>

So now we have a nice looking email that communicates everything we want with just providing an object tree to our template.  But of course that doesn't suffice.  We want to be able to differentiate templates between the action we have performed, that was one of the reasons why we created the small templates remember.  So if we modify the code where we load our template, we can choose a different template based on the action we had.

1 var group = new StringTemplateGroup(new StreamReader("templates\\TemplateEmail.st")); 2 var template = group.GetInstanceOf("EmaiForl"+action.Type); 3 4 template .SetAttribute("person", person); 5 template .SetAttribute("action", action); 6 7 var emailBody = query.ToString();

This means we need to have templates for the different actionTypes our application has, in our case these two templates would be required:

1 EmailForChangeAuthorization(person, action) ::= << 2 <WriteEmailHeader(person)> 3 <WriteEmailAction(action)> 4 \<br\> 5 This leads to changes in the permissions you have on our applications. 6 \<br\> 7 <WriteApplicationInformation(person)> 8 <WriteFunctionalityInformation(person)> 9 10 <WriteEmailEnding()> 11 >> 12 13 EmailForChangePassword(person, action) ::= << 14 <WriteEmailHeader(person)> 15 <WriteEmailAction(action)> 16 17 We are glad to inform you that your new password is <MakeBold(person.password)>, please 18 logon and change your password to something more personal. 19 20 <WriteEmailEnding()> 21 >>

 

That pretty much it.  If you want to have a look at it yourself, you can download the code or go have a look at the he Stringtemplate website.

zaterdag 2 augustus 2008

Simplify your life... decorate with aspects !

In the company that currently hired me tracing for instance (which is one of the areas you could benefit a lot from using aspects), is done my hand.  Every method (at least most of them)  follows the next format

public bool Method(params string[] inputValues) { Trace("Enter", "MethodName", inputValues); // trace all input parameters ..... bool someValue; ...... Trace("Exit", "MethodName", someValue); // trace parameters leaving the method return someValue }

If you only have to write code once and then never touch it again, maybe this way of developing would be acceptable.  But I rarely (read never) have been on a project where this was true.  Code will be refactorred and not only once.  Keeping the tracing parameters in sync with the constant refactorings is something that is often forgotten.  Compare it with the method documentation you write, if you would generate your ndoc now does it truly reflect your code??  My thoughts exactly, so help is needed, aspect orientation to the rescue.  If you Google aspect orientation (that's right I even saved you the time to do that) you will find many useful resources and implementations, today I will be taking a closer look into PostSharp

PostSharp performs a post compilation step to inject IL code, which means it can 'adapt' your entire code base even private methods,fields...  You can use PostSharp in two ways, the easiest is to download the msi file and install it on your machine.  If you are anything like me you hate installing software on your machine, you might have a look at this blog post from Gael Fraiteur the lead developer for the project.  He explains what happens under the hood and how the post compile step is called in msbuild.   

If now you add the required assemblies (PostSharp.public and optionally PostSharp.Laos) to your project, the post compilation step will automatically gets called from msbuild.  It will search your assembly for all required tasks to process and then updates the IL code.

First on my list is to improve my above tracing problem.  This is easily solved by overriding the OnMethodBoundaryAspect (provided as one of the higher level aspects of the PostSharp.Laos library) , this provides the following methods:

  • OnEntry : called when entering the method
  • OnExit : always called when exiting a method
  • OnException: called when the method resulted in an exception
  • OnSuccess: called when the method executed successfully

and leads to the following code:

public override void OnEntry(MethodExecutionEventArgs eventArgs) { Trace.WriteLine( string.Format("Enter {0}.{1}.", typename, methodname), this.category); } public override void OnExit(MethodExecutionEventArgs eventArgs) { Trace.WriteLine( string.Format("Leaving {0}.{1} with {2}", typename, methodname, eventArgs.ReturnValue), this.category); } public override void OnException(MethodExecutionEventArgs eventArgs) { Trace.WriteLine( string.Format("Exception {0}.{1}.", eventArgs.Exception.Message, eventArgs.Exception.StackTrace), this.category); } public override void OnSuccess(MethodExecutionEventArgs eventArgs) { // Usually you don't need this }

Another way to achieve this is to override the OnMethodInvocation.  This provides you with different methods to work with but you have the same functionality at your disposal.  The major difference is that this method does not modify your original method (as would happen with the above sample), but intercepts the call en invokes your OnInvocation method).  Check reflector to see the differences here!!

public override void OnInvocation(MethodInvocationEventArgs eventArgs) { // Perform tracing here Trace.WriteLine( string.Format("Enter {0}.{1}.", typename, methodname), this.category); try { base.OnInvocation(eventArgs); // Invoke your method here! } catch(Exception ex) { Trace.WriteLine( string.Format("Exception {0}.{1}.", ex.Message, ex.StackTrace), this.category); } finally { Trace.WriteLine( string.Format("Leaving {0}.{1} with {2}", typename, methodname, eventArgs.ReturnValue), this.category); } }

So far so good.  Applying these attributes is as simple as using other attributes in .NET, just decorate your method/class with them.  If off course you wish to perform tracing on an entire assembly or part of it, You will be adding a lot of these attributes, so a better way has been provided:  The following configuration intercepts all method calls from the Tracing.Model, Tracing.Repository and Tracing.Service namespace.    You could tweak this further.

[assembly: Trace(AttributeTargetTypes = "Tracing.Model.*")] [assembly: Trace(AttributeTargetTypes = "Tracing.Repository.*")] [assembly: Trace(AttributeTargetTypes = "Tracing.Service.*")]

You could specify on which the aspects (or attributes) can be applied by specifying the AttributeUsage and MulticastAttributeUsage, see the official documentation about that here (UserGuide -> Using PostSharp LAOS -> Wildcards and multicasting).

Secondly my I wanted to simplify my validation code.  One solution is to decorate my fields with the specification they have to obey.  For instance

  • A String field should contains maximally 16 characters
  • A Number must be between 1-100 (see the following code sample)
  • A Date must be in the future
[Serializable] public class RangeSpecification : OnFieldAccessAspect { public Int32 _minimum = 0; public Int32 _maximum = 100; public RangeSpecification(Int32 minimum, Int32 maximum) { _minimum = minimum; _maximum = maximum; } public override bool CompileTimeValidate(System.Reflection.FieldInfo field) { Console.WriteLine("RangeSpecification"); // this comes in the output window when compiling if (field.FieldType.Name != typeof(Int32).Name) { // "Why would you want to use this specification on a non number field?" return false; } return true; } public override void OnSetValue(FieldAccessEventArgs eventArgs) { Int32 exposedValue = Int32.Parse(eventArgs.ExposedFieldValue.ToString()); if (exposedValue < _minimum || exposedValue > _maximum) { // keep the old value when an invalid value was passed in eventArgs.ExposedFieldValue = eventArgs.StoredFieldValue; } base.OnSetValue(eventArgs); } }

So far the first exploration of PostSharp, I  realize this was only the top of the possibilities but I hope everybody can see how much code can be saved and might not clutter your production code by applying these aspects correctly in your code.

See you next time.

dinsdag 29 juli 2008

Ignore files in your subversion repository

After reading the pragmatic programmer in my holiday I decided it was time to put theory into practice.  Whenever I perform an check-in in my subversion repository I usually deleted my bin and obj folders manually to make sure they didn't got checked-in.  Of course tortoiseSVN and subversion provides ways to automatically exclude them when you check-in.

So in order to 'avoid my repetitive tasks' and win those crucial couple of seconds on every commit (have you ever count how much this could add-up to on a year basis?) I browsed the tortoise site and found the following documentation:

http://tortoisesvn.net/docs/nightly/TortoiseSVN_en/ch05s11.html#tsvn-DUG-ignore-glob

Here are the settings that I've applied on my projects : */bin */obj */_ReSharper* *.suo *.user *.resharper

image

Right where can I win some more time, maybe I can achieve my 4 hour work week!

maandag 7 juli 2008

Book Reviews: the holiday books

Just returned from my holiday where I had the time to catch up on my reading. I choose a couple of books from my shelf and went on my way to France.

The pragmatic programmer

This book is all about becoming a better and more productive developer.  The book contains tips and tricks to let you focus on the job at hand instead of distracting you from it.  It reads like a novel so it is perfect as holiday lecture (buy this book if you are leaving in the next couple of weeks).

I simply cannot believe that this book is written 10 years ago.  It still is burning accurate and besides the referral to the "upcoming language of java" and "in the future there will be refactorings tools available" you simply cannot tell it is this 'old'. 

I really liked the way the book compared the continuously studying everyone has to do with investing in your stock portfolio, it's all about diversification! 

As a nice extra for one of my colleagues  the books describes nicely the pussy way of development.  :-)

Agile principles, patterns and practices in C#

A must read book for everyone doing agile development in C#.  It starts of with a section explaining what agile development is all about and what are its cornerstones.  The section ends with an hilarious 'role play story on pair programming'. 

The second section is more interesting where all the basic principles of software development pas the revue.  If you don't know what the Single Responsibility  principle, what the open/closed principle has to do when there are no doors involved, when LSP, DIP and ISP are just meaningless acronyms then this book is for you.  The section finishes of with an overview of UML and how to express design in various diagrams.

Section three and four covers the patterns part of the book and it does this by following a case study about a payroll system.  If you have heard of NDepend you will probably be familiar with the principles (REP, CRP, ....) Robert explains when packaging our case study.

I would advice this book to everyone who wants to start with agile development!

I then started to read Implementation patterns from Kent Beck, but the didn't finish it yet.  The swimming pool looked more appealing...

donderdag 12 juni 2008

The pain of development in Vista

I recently bought a new laptop with Windows Vista already pre-installed.  Until that time my development machine was running on XP, but now I had the joy of meeting the latest invention (??) of Microsoft called User Access Control (UAC)!  I am still figuring out if this is supposed to be feature or a bug that the programmers could not fix. 

My problem is the following: Whenever I open a perfectly working solution on my new machine I got an annoying "System.Runtime.InteropServices.COMException" exception hitting me.  I quickly realized it happened only when accessing a Web or Service through IIS.  Whenever you want to access local IIS Website your Visual Studio needs to fired up in the context of an administrator, by default Vista starts applications in a limited-privilege user account.  The solution to this problems is relatively easy, always start your studio in administrator mode.  I created a new shortcut that runs in administrator mode and associated my sln-files to use this shortcut by default.  If you right-click on a shortcut, in the advanced tab you can select the 'run in administrator' option.

Problem solved if you can live with a UAC popup every time you open Visual Studio.  If you anything like me you want to avoid this popup as well :-), my first thought was simply disable the UAC Altogether, but then other features might stop working because windows believes your system is not trustworthy.  Since I usually select proceed in those useless popups I decided to accept this silently without prompting, you can read here how this can be achieved.  I took the liberty of giving you summary here:

Click Start and Control Panel. Switch to Classic View (if you haven't already) and click on the Administration Tools icon. In the list that opens click on Local Security Policy, and in the next window, Local Policies (a tiny bit redundant, but all UIs can't be perfect -- If UAC is running you'll get a UAC pop-up somewhere in here). In the Local Policies list click Security Options, and scroll down to "User Account Control: Behavior" (the full title of the policy is "User Account Control: Behavior of the elevation prompt for administrators in Admin Approval Mode" but the window barely opens that far). Double-click the title and in the dialog box change its setting from "Prompt for Consent" to "Elevate without prompting." Click OK and the urge to tear your hair and scream at your PC will be greatly diminished in the future.

I hope this post will save you time and headache, till next time.

donderdag 5 juni 2008

NHibernate in Action: Book Review

I finished this 'beta' book today, it took me a while because I have the bad habit of reading multiple books at the same time.  For an NHibernate virgin like myself the book was a very good introduction. It covers everything you need to know to get started with release 1.2.1 version, although nothing is inserted (yet ?? ) for the upcoming 2.0 release.  I hope the final version will include some chapters covering the new features, especially the event/listener model seems to be interesting.  If it doesn't the book might already be outdated upon its release in August.

The thing I was missing was more in depth information about extending the functionality of NHibernate.  We had an issue for instance with the interceptors which you can read all about here, but the book did not provide a lot of information about. 

My overall conclusion is positive because it was a nice intro, but if you already have some experience with NHibernate the book  might be too 'easy' for you.