Topic: tools

I have been writing a blog on and off for a few years now. During this time I have moved from several different blog engines and services to finally a setup that I think makes sense.

Text Files

My first blog was a set of text files that I maintained and manually converted to html files hosted on a server running from my bedroom in my parents basement. When I got to work in the mornings I would RDP to my machine at home and write my posts in notepad. Then I would copy and paste the content of the text file into an html template and copy the new file to my site.

MSN Spaces, Blogger, DasBlog

After about a month of that crazy setup I created a blog on MSN Spaces, then moved to Blogger. After a while I decided to switch to DasBlog hosted on a shared GoDaddy server. I ran DasBlog for a few years. It worked great with Windows Live Writer and make it really easy to create and publish new posts. To convert a thought to a written post sitting on the interwebs was quick and easy.

Wordpress

After a while I decided to spend some time converting my DasBlog to a wordpress blog. I think it was James who sparked the idea after a conversation we had, and some guidance that he offered.

Jekyll - Text Files (Again?)

Then came Jekyll. A static site generation tool. I began writing my posts in a format known as markdown and used jekyll to generate html files from my markdown posts.

I quickly fell in love with Jekyll because now I had an easy system for writing posts in the editor of my choice, and I could for the first time actually put my blog in version control. I no longer needed a backend database or heavy infrastructure to run my website.

Along came, Octopress. Octopress is an enhanced system of generating posts and deploying a site on top of Jekyll. I found that I still preferred working off jekyll because it's a lighter weight system that I can control to my liking. However, if I were to start a new blog from scratch today, I think Octopress would be a good choice.

My Current Setup

Today, I host the source markdown files and jekyll project in a private FREE repository hosted on bitbucket, and I deploy the generated static site to a FREE GitHub account via GitHub pages.

The cost to host my site is $FREE.99. I use the free Google Apps plan to manage my email, calendar, docs etc. I pay my domain registrar to register my domain and host my DNS.

What about dynamic content?

What dynamic content?

I user sevices like WuFoo to manage a contact form for me, and UserVoice to collect feedback and suggestions. I ported the comments from my old posts from DasBlog into wordpress and now into Disqus. I use Google Analytics to track keywords and visits to my site.

It's been a fun circle starting on text files, and coming write back to them.

Recently, I have been having some fun with C# and Mono. I decided to try to abandon visual studio, resharper, and windows and start writing from vim on my unix machines. Inspired by Gary Bernhardt and Destroy all Software.

vim

My vim configuration started to become a giant mess, as I started moving from Windows to Ubuntu to OSX. So a few months ago, I totally abondoned my vim configuration in favor of Janus.

Janus, is a vim distro with a bunch of plugins, snippets, and goodies all baked right in. This makes it incredibly easy to switch from your editor of choice to vim.

One of the fun things I learned from one of the Destroy all screencasts is to map ',t' to run your tests from vim.

Instead of using GVim or MacVim, I have been running vi from within iTerm 2/Terminal. Then I map ,t to a command that will run my tests for the current project.

  :map ,t :w\|:!rake spec<cr>

Instead of alt+tabbing back and forth between my editor and shell to run my tests. I can now seemlessly switch back and forth from running tests, to writing code all from one environment.

xbuild

For building projects, the Mono equivalent to msbuild is xbuild. It's super easy to use and works as I expected. On Ubuntu you can install via:

  sudo apt-get install mono-xbuild

To build your csproj, just jump back into your shell and run

  xbuild src/test/test.csproj '/target:Clean;Rebuild' /verbosity:quiet /tv:4.0 /nologo

nuget

I was having some issues trying to figure out how to install packages using NuGet and Mono on both my OSX machine, and Ubuntu machine. Thankfully, I came across this post which helped me finally get things working as expected. nuget on mono

The key to my success was to specify the runtime version. Without it, mono seems to default to the 2.0 runtime, and NuGet uses the 4.0 runtime.

  $ mono --runtime=v4.0.30319 NuGet.exe

The NuGet commandline tool can be downloaded from here and the command line reference is available here

unit testing

Machine.Specifications runs just fine under Mono. There's not much for me to say here expect, Thank You!

I 'borrowed' DevelopWithPassions continuoustesting script to be able to listen for changes to my .cs files to automatically start running tests in the background, then pop up a growl notification when a test fails. I'm not sure if I prefer having my tests running automatically or if I prefer to control when I want to run my tests. Sometimes it seems like a little to much noise with all the growl notifications, since I tend to save quite often.

annoying

I was surprised at how easy it is to write C# outside of the windows eco system. There are still a few things that are kind of annoying. I find it really annoying to have to manually update the csproj file anytime I add or remove a file. I also miss being able to hit alt+enter and allow ReSharper to automatically include the proper namespace. Although, it has been fun exercising my ability to remember which System namespaces need to be included.

conclusion

I'm having fun with this experiment. 'nuff said

follow along

  git clone git://github.com/mokhan/cs_practice.git

My mac book pro arrived on Monday and since then I've spent most of my time trying to figure out some settings that I consider to be basic.

  • mapping capslock to escape
  • swap fn and ctrl
  • keyboard shortcut to maximize a window
  • keyboard to active/deactive fullscreen

mapping caps lock to escape

I can't believe how difficult this is. In ubuntu this is a simple keyboard setting, but sadly on OSX I had to install some thirdparty software to do this. The tools i used was PCKeyboardHack

swapping fn and ctrl

I am used to having the ctrl key in the bottom left corner of the keyboard so i found it more natural to swap the two keys. To do this i used KeyRemap4Macbook

keyboard shortcut to maximize a window

I'm currently trying this script in combination with quicksilver triggers and mapped to cmd+ctrl+z. So far i'm not liking this setup. I prefer winkey + up on windows or alt + f10 on ubuntu.

keyboard shortcut to activate/dectivate fullscreen.

To do this follow the instructions here. Unfortunatly, the cmd + escape combination did not work for me so i opted for ctrl+cmd+f

working with screen in bash in terminal

To get screen to and bash to function properly and recognize your .rvmrc project files follow the instructions in this post

.bashrc

1 alias screen='export SCREENPWD=$(pwd); /usr/bin/screen'
2 export SHELL='/bin/bash -rcfile ~/.bash_profile';
3 
4 case "$TERM" in
5     'screen')
6              cd $SCREENPWD
7                       ;;
8                       esac

.screenrc

1 startup_message off
2 shell -$SHELL

customizing the terminal prompt

to get your prompt to look like mine ie.

mo@mobook ~/development/blah
$ 

.bashrc

export PS1="\u@\h\w \n$ "

installing imagemagick properly

Follow the instructions found on this stackoverflow post

1   brew remove imagemagick
2 
3   rm -rf 'brew --cache imagemagick'
4 
5   brew install -f imagemagick --disable-openmp

how to source .bashrc by default in terminal

read this

/etc/profile

1   [ -r $HOME/.bashrc ] && source $HOME/.bashrc

Top 4 picks

jasmine

qunit

screwunit

#

other libs

helpful links

freenx is like remote desktop (mstsc.exe). The way it works is you have to run a NX server on the box that you want to remote in to. You then use a NX Client to remote in to the box.

There's a great Community Doc page for getting up and running on Ubuntu.

If you don't already have SSH set up, you will probably want to get that up and running first.

Below is a short version of what I ran to get up and running on 10.10.

Install Server

  $ sudo add-apt-repository ppa:freenx-team
  $ sudo sed -i 's/maverick/lucid/g' /etc/apt/sources.list.d/freenx-team-ppa-maverick.list
  $ sudo apt-get update
  $ sudo apt-get install freenx
  $ cd ~/Downloads
  $ wget https://bugs.launchpad.net/freenx-server/+bug/576359/+attachment/1378450/+files/nxsetup.tar.gz
  $ tar -xvf nxsetup.tar.gz
  $ sudo cp nxsetup /usr/lib/nx/nxsetup
  $ sudo /usr/lib/nx/nxsetup --install

Install Client

There seems to be several NXClients available but I chose to try the NoMachine client which can be downloaded from here.

How do you replace a deprecated application that was built on top of Microsoft Content Management System (MCMS) 2002?

You could recursively download the entire website and serve it up as static html pages. This is where you use a tool like wget.

  $ sudo apt-get install wget

or download the wget package via cygwin.

  $ wget -r -p http://mokhan.ca/

And there you have it. You now have a local copy of the target website.

If you notice that some content wasn't pulled down, that should have been, it's likely because the site has a robots.txt file at root that disallows certain urls.

links

To install ssh in ubuntu

$ sudo apt-get install openssh-client openssh-server

To install in cygwin install the openssh package under "net". You will also need to run "ssh-host-config" after install to run the server.

Then to ssh into your machine use the below command. The standard port is 22, but you should change this. You can either update the config file located at "/etc/ssh/sshd_config" or you can do a port forward on your public facing firewall.

  $ ssh mo@<server> -p <port>

To copy files from a remote machine down to your local machine you can use the scp command.

# copy from a remote machine to my machine:
  $ scp user@192.168.1.100:/home/remote_user/Desktop/file.txt /home/me/Desktop/file.txt

# copy from my machine to a remote machine:
  $ scp /home/me/Desktop/file.txt user@192.168.1.100:/home/remote_user/Desktop/file.txt

# copy all file*.txt from a remote machine to my machine (file01.txt, file02.txt, etc.; note the quotation marks:
  $ scp "user@192.168.1.100:/home/remote_user/Desktop/file*.txt" /home/me/Desktop/file.txt

# copy a directory from a remote machien to my machine:
  $ scp -r user@192.168.1.100:/home/remote_user/Desktop/files /home/me/Desktop/.

SSH & GIT

When you need to manage public/private keys for different git repositories on one machine you can use a config file in your ~/.ssh/ directory. Using the config file you can specify which keys to use for specify urls.

For example the following is a sample ssh config file.

Host github.com
  User git
  Hostname github.com
  PreferredAuthentications publickey
  IdentityFile ~/.ssh/github/id_rsa

Host unfuddle.com
  User git
  Hostname unfuddle.com
  PreferredAuthentications publickey
  IdentityFile ~/.ssh/unfuddle/id_rsa

In some cases you may need to "ssh-add ~./ssh/github/id_rsa" each public key/pair. You may also have to "chmod 600 ~/.ssh/github/*"

To figure out what key is being supplied when cloning a git repo you can ssh to the destination server using the git user. The following command should give you enough information to figure out what's going on.

  $ ssh -v git@github.com

SSHFS

To mount a remote filesystem.

  $ mkdir ~/godaddy
  $ sshfs -C user@user.com: ~/godaddy
  $ ls ~/godaddy

To unmount

  $ fusermount -u ~/godaddy

mount a remote file system

This is a collection of information that I have learned since I started using Ubuntu 10.4 back in August of 2010. Since then I have upgraded to 10.10 and have been using it as my primary OS on my voodoo laptop. It has been a super powerful OS, with pretty much everything I need in an OS to use my laptop.

There are a couple of things that I have had issues with: One is getting my Microsoft LifeCam to work nicely with Skype, and well I haven't fired up Visual Studio on my laptop in months.

links

TV

Hauppage WinTV PVR 150

I have a tv tuner card hooked up to my pc as well as a logitech webcam. To watch tv on my pc I can open up VLC and:

  • Media (alt+M)
  • Open Capture Device (ctrl+C)
  • Capture Mode = PVR
  • Device Name = "/dev/video1" -- this should be set to your tv tuner video device you can find out what number is assigned to your tuner by using v4l2-ctl --list-devices
  • then press Play

VLC will then start playing whatever channel the card is currently configured to point to.

To change channels you can open up Terminal and enter

  $ ivtv-tune --channel=21

Fine tuning

  $ v4l2-ctl -n # to find out what inputs are available on the current device
  $ v4l2-ctl -i 1 # to change the current device to input 1
  $ v4l2-ctl -d/dev/video1 # to change devices
  $ ivtv-tune --channel=21 -d/dev/video1 # to change to channel 21 on the device 1
links

Mounting an internal drive

tools * [gnu screen] * tutorial * quick ref

packages

  • ruby
  • python
  • ncurses
  • openssh
  • wget
  • gcc
  • lynx

ruby

To get ruby working on both windows and cygwin you need to unset the RUBYOPT variable in your ".bash_profile"

1   unset RUBYOPT

gems

  • gem install rdiscount
  • gem install jekyll
  • gem install jekyll_ext
  • gem install vmail

python

Install the python package under cygwin. then to get easy_install

1   $ wget http://peak.telecommunity.com/dist/ez_setup.py
2   $ python ez_setup.py

sourced from server fault

Then to get pygments:

1   $ easy_install Pygments

sourced from github

To Do

These are things that I need to figure out how to accomplish under cygwin.

  • find equivalent to "start ." or "nautilus ."
  • launch gvim from shell. e.g "gvim ."
  • figure out why vmail does not work.
  • kill windows processes e.g. "ps msbuild.exe | kill"
  • install inconsolata font

my git-svn workflow

  • git svn clone http://svn-repo -T trunk -b branches -t tags
  • cd svn-repo
  • git svn rebase
  • git branch -f development
  • git checkout development
  • gvim hello-world.mkd -- edit file
  • gvim goodbye-world.mkd -- edit file
  • git add .
  • git commit -am "added hello world, and good bye"
  • git checkout master
  • git svn rebase
  • git merge --squash development
  • git commit -- squash commit message
  • git svn dcommit
  • git branch -f development
  • git checkout development
  • rm goodbye-world.mkd
  • git add -A
  • git commit -am "removed goodbye."
  • git checkout master
  • git svn rebase
  • git merge --squash development
  • git commit -- edit and squash the commit message.
  • git svn dcommit

To create an SVN tag from git.

1   $ git svn branch -t {tagname}

creating an ssh key

$ cd ~/.ssh $ ssh-keygen -t rsa -C "email@mokhan.ca"

managing multiple accounts

in your .ssh config you can specify which rsa keys to use for different domains. e.g.

1     ~/.ssh/config
2     Host project1.unfuddle.com
3         User git
4         IdentityFile ~/.ssh/project1/id_rsa
5 
6     Host *.unfuddle.com
7         User git
8         IdentityFile ~/.ssh/id_rsa

hosting git yourself

1 $ sudo adduser git
2 $ login git
3 $ mkdir test.git
4 $ cd test.git
5 $ git init --bare
6 $ git remote rm origin
7 $ git remote add origin git@server.com:test.git
8 $ git push origin master

git submodules

tutorial fix path * on windows I had to fix the path in .gitmodules from .\src\Messages to src/Messages

submodules for git-svn

tutorial

links

tips for intermediates git svn externals private git server setup

One of the coolest things about powershell is being able to customize the shell. Here’s what my shell looks like now.

powershell.prompt

When I’m working on a project using git, my prompt looks like this.

powershell.prompt.git

It now tells me what branch i am on. Whoa… All I had to do was drop a modified version of profile.ps1 into “c:\users\mo\documents\WindowsPowerShell”. If the “WindowsPowerShell” folder doesn’t exist, then create it. That’s what I did. This is also using posh-git. If you checkout the source you’ll find an example of the profile.ps1 that you can use.

Leveraging this file you can load other scripts every time you pop open a powershell. Like if you wanted to load a sweet twitter script. Here’s my current script…

Import-Module d:/scripts/posh-git/posh-git
d:\scripts\twitter-on-powershell\twitter-on-powershell.ps1
d:\scripts\vsvars2010.ps1

function prompt {
    $user_location = $env:username + '@' + [System.Environment]::MachineName + ' /' + ([string]$pwd).replace('\', '/').replace(':', '').tolower() + ' ~'
    $host.UI.RawUi.WindowTitle = $pwd
    Write-Host($user_location) -foregroundcolor green
    # Git Prompt
    $Global:GitStatus = Get-GitStatus
    Write-GitStatus $GitStatus
    return "> "
}

if(-not (Test-Path Function:\DefaultTabExpansion)) {
    Rename-Item Function:\TabExpansion DefaultTabExpansion
}

function TabExpansion($line, $lastWord) {
    $lastBlock = [regex]::Split($line, '[|;]')[-1]
    switch -regex ($lastBlock) {
        # Execute git tab completion for all git-related commands
        'git (.*)' { GitTabExpansion $lastBlock }
        # Fall back on existing tab expansion
        default { DefaultTabExpansion $line $lastWord }
    }
}

Enable-GitColors

The cool part is that everything you write in a powershell console can be dropped right in to a .ps1 file and run as a script. I’m actively learning…

I'm still surprised by just how many people still aren't using ReSharper. It's an amazing productivity adding for Microsoft Visual Studio.  Once you've spent the time learning a few keyboard shortcuts you will not go back to naked studio.

There are few things that are more frustrating then jumping on a machine that doesn't have ReSharper installed, then trying to edit some .cs files.

In an effort to prevent myself from ever having to jump on a pc that's still missing the glory of ReSharper, I decided to throw together a quick screen cast showcasing some of the features i enjoy.

ReSharper Warm Fuzzies Screen cast

If you haven't already. please, please give it a try (do it for me). It's a good addiction!

In an attempt to further understand BDD, I chose to revise the code from my previous post after receiving some amazing advice from two people I regard highly (Scott & JP). I should state that this is my interpretation of that advice. This may or may not be the direction they were trying to guide me towards.

 1   public class when_prompted_to_save_changes_to_the_project : concerns_for<SaveChangesView>    
 2   {    
 3     context c = () => { presenter = an<ISaveChangesPresenter>(); };    
 4 
 5     after_the_sut_has_been_created after = () =>    
 6                                                 {    
 7                                                     save_changes_window = sut;    
 8                                                     save_changes_window.attach_to(presenter);    
 9                                                 };    
10      
11     protected static ISaveChangesPresenter presenter;    
12     protected static SaveChangesView save_changes_window;    
13   }    
14      
15   public class when_the_save_button_is_pressed : when_prompted_to_save_changes_to_the_project    
16   {    
17       it should_save_the_current_project = () => presenter.was_told_to(x => x.save());    
18      
19       because b = () => save_changes_window.save_button.control_is(x => x.OnClick( new  EventArgs()));    
20   }    
21      
22   public class when_the_cancel_button_is_pressed : when_prompted_to_save_changes_to_the_project    
23   {    
24       it should_not_continue_processing_the_previous_action = () => presenter.was_told_to(x => x.cancel());    
25      
26       because b = () => save_changes_window.cancel_button.control_is(x => x.OnClick( new  EventArgs()));    
27   }    
28      
29   public class when_the_do_not_save_button_is_pressed : when_prompted_to_save_changes_to_the_project    
30   {    
31       it should_not_save_the_project = () => presenter.was_told_to(x => x.dont_save());    
32      
33       because b = () => save_changes_window.do_not_save_button.control_is(x => x.OnClick( new  EventArgs()));    
34   }

I hope this is slightly more soluble, then my previous post.

In the last couple of weeks I had a chance to sprinkle some of JP's syntactic sugar, all over my projects. It's amazing how much more concise my units test have become. I've had a couple of issues where I was mocking out the behavior of some Win Forms controls, but for the most part it's been an awesome experience!

I just wanted to take a moment to say Thank you JP! I am enjoying using your BDD (on steroids) extensions. If you haven't already you need to check it out here. NOW!

Maaad, maaaad props Mr. JP!

 1    
 2 
 3   public class behaves_like_save_changes_view_bound_to_presenter : concerns_for<SaveChangesView>    
 4   {    
 5     context c = () => { presenter = an<ISaveChangesPresenter>(); };    
 6     because b = () => sut.attach_to(presenter);    
 7 
 8     static protected ISaveChangesPresenter presenter;    
 9   }    
10     
11   public class when_the_save_button_is_clicked : behaves_like_save_changes_view_bound_to_presenter    
12   {
13 
14     it should_forward_the_call_to_the_presenter = () => presenter.was_told_to(x => x.save());    
15 
16     because b = () => EventTrigger.trigger_event<Events.ControlEvents>( new EventArgs()), sut.ux_save_button);
17 
18   }
19     
20   public class when_the_cancel_button_is_clicked : behaves_like_save_changes_view_bound_to_presenter    
21   {    
22     it should_forward_the_call_to_the_presenter = () => presenter.was_told_to(x => x.cancel());
23 
24     because b = () => EventTrigger.trigger_event<Events.ControlEvents>(x => x.OnClick(new EventArgs()),sut.ux_cancel_button);    
25   }    
26 
27   public class when_the_do_not_save_button_is_clicked : behaves_like_save_changes_view_bound_to_presenter    
28   {
29     it should_forward_the_call_to_the_presenter = () => presenter.was_told_to(x => x.dont_save());
30 
31     because b = () => EventTrigger.trigger_event<Events.ControlEvents>( x => x.OnClick(new EventArgs()), sut.ux_do_not_save_button );
32   }

Update: I posted the wrong link up top. here's the latest link.

So I recently started twittering... or tweeting. I'm not sure what the correct lingo is, so hook me up if you know. It all started a while back when James announced that he was the newest Twit. He mentioned a WPF client called Witty, and I wanted to see what it was all about. So I setup a Twitter account to play with the app. After I had my fun, I never deleted my account. Or at least I never looked into how to delete my account.

About a week ago I received and email that a couple of people were following me on Twitter. Man that's flattering to read:

Hi, mo_khan.
Kyle Baley (kbaley) is now following your updates on Twitter.
Check out Kyle Baley's profile here:
http://twitter.com/kbaley
You may follow Kyle Baley as well by clicking on the "follow" button.
Best,
Twitter

Whaa... a celeb is interested in what I'm up to? *blush* So I jumped in, and so far it's been pretty fun. I found another service called "Jott". Jott's pretty cool, because I can call in to a number and I get an automated message that says:

"Who do you want to jott?"

I say ... "Twitter". Then I record my voice message.

Jott then takes that message transcribes it in to text, pushes it up to my twitter page, and drops a tinyurl to the actual audio. Sweet... that saves me a few pennies worth of text messages. But there's more...

I'm one of the poor saps who pay to much for mobile service up here in Canada, eh! I subscribe to Rogers Wireless, and the plan called "My5". I get to make unlimited phones calls to the 5 numbers that are in My5? So I put Jott on My5, and now I can shoot off messages to everyone for....

Free Ninety Nine.... well almost! If you're young, fabulous and ghetto broke (it aint funny) like myself then you ought to give Jott a try!

In my last post I briefly mentioned how we were wiring some components in to our container.  The syntax looked like the following:

1   container.AddProxyOf(
2       new ReportPresenterTaskConfiguration(), 
3       new ReportPresenterTask(
4           Lazy.Load<IReportDocumentBuilder>(),
5           Lazy.Load<IApplicationSettings>())
6           );

We're using Castle Windsor under the hood, but we have an abstraction over it that allows us to configure it as we like. Even switching the underlying implementation. Which we did, from our hand rolled container to Castle Windsor. The implementation of the above method looks as follows:

1   public void AddProxyOf<Interface, Target>(IProxyConfiguration<Interface> configuration, Target instance) where Target : Interface
2   {
3       var builder = new ProxyBuilder<Interface>();
4       configuration.Configure(builder);
5       AddInstanceOf(builder.CreateProxyFor(instance));
6   }

Wikipedia defines the Proxy design pattern as:

A proxy, in its most general form, is a class functioning as an interface to another thing.

To understand the ProxyBuilder implementation you can checkout JP's strongly typed selective proxies. The "AddProxyOf" method creates an instance of a proxybuilder. It then passes it to the configuration to allow it to configure the proxy builder before building the proxy. Then it registers the proxy as a singleton in to the container.

1     public interface IConfiguration<T>
2     {
3         void Configure(T item_to_configure);
4     }
5 
6     public interface IProxyConfiguration<T> : IConfiguration<IProxyBuilder<T>>
7     {
8     }

In this case the proxy configuration looks like:

1     public class ReportPresenterTaskConfiguration : IProxyConfiguration<IReportPresenterTask>
2     {
3         public void Configure(IProxyBuilder<IReportPresenterTask> builder)
4         {
5             var constraint = builder.AddInterceptor<DisplayProgressBarInterceptor>();
6             constraint.InterceptOn.RetrieveAuditReport();
7         }
8     }

This guy adds a progress bar interceptor, that displays a progress bar as the report is getting generated via the "RetrieveAuditReport" method on the IReportPresenterTask.

I love being the guy to hit 1000 tests first... I guess I should check in first. doh!

one_thousand_tests

Recently, we've been mocking out IQueryable's as return values, which had led to setups that look like the following...

1   programs.setup_result_for(x => x.All()).Return(new List<IProgram> {active_program,inactive_program}.AsQueryable());

I just switched over to the following syntax... by creating an extension method.

1   programs.setup_result_for(x => x.All()).will_return(active_program,inactive_program);

The following are the extensions methods to make this work.

1   public static IMethodOptions<IEnumerable<R>> will_return<R>(this IMethodOptions<IEnumerable<R>> options, params R[] items)
2   {
3       return options.Return(items);
4   }
5 
6   public static IMethodOptions<IQueryable<R>> will_return<R>(this IMethodOptions<IQueryable<R>> options, params R[] items)
7   {
8       return options.Return(new Query<R>(items));
9   }

and...

 1   internal classQuery<T> : IQueryable<T> 
 2   { 
 3      private readonly IQueryable<T> query; 
 4   
 5    public Query(params T[] items) 
 6    { 
 7      query = items.AsQueryable(); 
 8    } 
 9   
10    public Expression Expression 
11    { 
12      get { return query.Expression; } 
13    } 
14   
15    public Type ElementType 
16    { 
17      get { return query.ElementType; } 
18    } 
19   
20    public IQueryProvider Provider 
21    { 
22      get { return query.Provider; } 
23    } 
24   
25    public IEnumerator<T> GetEnumerator() 
26    { 
27      return query.GetEnumerator(); 
28    } 
29   
30    IEnumerator IEnumerable.GetEnumerator() 
31    { 
32      return GetEnumerator(); 
33    } 
34   }

Hope, this helps!

Today I received an email about the JetBrains Seeder Program, and thought that I would try to sign up for an account to find out more.

Can you help me understand, what JetBrains is trying to tell me?

jetbrains_subliminal_messages 

horning

So yesterday I had this idea on how to run a background thread using an interceptor, but first I needed to Grok how the castle interceptors worked. I quickly ran into a snag, it looked something like this:

background_thread_interceptor

The problem is that the latest version of Rhino.Mocks hasn't internalized the castle dependencies. So the compiler doesn't know whether I'm referring to Castle.Core.Interceptor.IInvocation from the Castle.Core.dll or Castle.Core.Interceptor.IInvocation from Rhino.Mocks.dll.

I'm not sure why this is, so I did a little digging. And found this post... In one of the last comments someone else had this same issue...

rhino_mocks_internalize_castle_dependency

I'm not really sure what this meant, so I decided to pull the source from the trunk. In the Rhino.Mocks project there's a file called "ilmerge.exclude" and in it was the interface that I was having trouble resolving (IInvocation). I removed it from the file, and rebuilt a release version. Seems to be working now.... I'm still not sure why this change was made... which makes me feel a bit uneasy.

ilmerge_diff

Try it at your own discretion.

Oh man... oh man! JP's puttin' on a contest and givin' away free stuff... Lot's of it! *drool*

It's kind of a cool idea... The gist of it is to describe how YOU are contributing to the community, and how YOU are leaving an impact on those around you. It's all about YOU!

I can think of a few people that I have definitely left an impact on my life. If anyone's left an impact on you, why not nominate them!

The first place winner of the contest...

wins a seat at the Nothin' But .NET Boot Camp, held in Las Vegas! That's about $3000 bucks for that seat alone! Plus... they get a copy of Visual Studio 2008 Team Suite... Plus a full years subscription to an MSDN Premium subscription.

I have no idea what an MSDN Premium subscription is... so I Googled it, here's what I found:

"MSDN Subscriptions are the ultimate resource for professional Developers, teams and organizations..." - http://msdn.microsoft.com/en-us/subscriptions/aa718661.aspx

Oh man, oh man... not only do you get a first class ticket to one of the most fulfilling courses you'll ever take, but.... you also get the ultimate resource for professional developers. If that doesn't get you all the fame and glory you've ever wanted... I'm not sure what will!

The second place winner...

wins a stack of books, and tools and another copy of Visual Studio 2008 Team Suite with another fully year subscription to MSDN.

The books are wicked too, not to mention expensive! You get...

  • The Pragmatic Programmer
  • Code Complete
  • Refactoring
  • Head First Design Patterns
  • Design Patterns
  • Test Driven Development
  • CLR via C#
  • Working Effectively with Legacy Code
  • Domain Driven Design
  • Agile, Principles, Patterns and Practices in C#.

I've read everyone of these books except for the last one. I can honestly say, I would read them over and over again. In fact, I am... and the tools.... oh man the tools... once you go ReSharper you'll never go back to naked studio, you just can't physically do it. It makes you physically ill... I puked once trying to do it... it was messy!

The third place winner...

wins a gift card from Amazon worth $140 bucks... That's quite a few books for a starving reader.

For more information go read up on the contest here...

Thank you Mr. Aaron, today we just grabbed the latest beta version of Rhino.Mocks and out test times significantly dropped....

Our times before the update were 450ish seconds to run all the unit tests and create the report:

before

Our times after are 100ish seconds:

after

Loading a subversion repository from a dump file isn't as hard as I thought it would be. It's as easy as:

> svnadmin path.to.repository.directory < repository.dump.file

You just have to make sure that:

  • you've got subversion installed or that you can hit "svnadmin.exe" directly.
  • the "path.to.repository.directory" has a repository created in it.

All that this seems to be doing is replaying every commit that ever happened on the original repository. This is pretty sweet, especially for a class room set up when the student afterwards want to go through different revisions to compare changes or things learned in class.

svn.dump

This month I read...

Refactoring: Improving the Design of Existing Code (The Addison-Wesley Object Technology Series)
by Martin Fowler, Kent Beck, John Brant, William Opdyke, Don Roberts

Read more about this title...

This book is awesome and a must read for anyone who enjoys the art of refactoring as much as I do. The examples are crystal clear and the way the refactorings are done step by step makes it so much more understandable.

Here are a few excerpts that I enjoyed from this book.

"The problem with copying and pasting code comes when you have to change it later. If you are writing a program that you don't expect to change, then cut and paste is fine. If the program is long lived and likely to change, then cut and paste is a menace."

I've got to agree and disagree with the above statement. I think anytime you find yourself copying and pasting is a clear sign of duplication which should be improved. Removing duplication should be something we all strive for, and remember that inheritance is not the only way to remove duplication. Proper object composition, delegation and generics are all great ways to remove duplicate code.

Replace conditional with Polymorphism has to be by far one of my favorite refactorings. If you're seeing if-else statements scattered throughout your code base that's a smell. Switch's are no better... (booo switches...)

"Is renaming worth the effort? Absolutely. Good code  should communicate what it is doing clearly, and variable names are a key to clear code. Never be afraid to change the names of things to improve clarity."

Amen, brother! Thank goodness for tools like Resharper and Rhino.Mocks. On my current project we're using NMock2 and I got burned several times doing a Rename Method because of the string literals used in NMock tests... My advice is just use Rhino Mocks... please... for my sake!

"You write code that tells the computer what to do, and it responds by doing exactly what you tell it. In time you close the gap between what you want it to do and what you tell it to do. Programming in this mode is all about saying exactly what you want. But there is another use of your source code. Someone will try to read your code in a few months' time to make some changes. We easily forget that extra user of the code, yet that user is actually the most important."

"The first time you do something, you just do it. The second time you do something similar, you wince at the duplication, but you do the duplicate thing anyway. The third time you do something similar, you refactor."

I often heard the term "smell" used as a way to describe something funky in a code base or team but I had no idea where the term came from... until know!

"If it stinks, change it." - Gradma Beck, discussing child-rearing philosophy

The chapter on code smells is awesome, it's offers a catalog of code smells like:

  • Duplicate Code
  • Long Methods
  • Large Classes
  • Long Parameter Lists
  • Divergent Changes
  • Shotgun Surgery
  • Feature Envy
  • Data Clumps
  • Primitive Obsession
  • Switch Statements
  • Parallel Inheritance Hierarchies
  • Lazy Class
  • Speculative Generality - "Oh, I think we need the ability to do this kind of thing someday."
  • Temporary Fields
  • Message Chains
  • Middle Man
  • Inappropriate Intimacy
  • Alternative Classes with Different Interfaces
  • Incomplete Library Classes
  • Data Classes
  • Refused Bequest - "Subclasses get to inherit the methods and data of their parents. But what if they don't want or need what they are given?"
  • Comments

If you only read one chapter in this book, I suggest Chapter 3. "Bad Smells in Code". I really like how Resharper uses the same refactoring names as those mentioned in this book. Anyway's, what are you waiting for go read this book.

Earlier this month I read...

Pragmatic Version Control: Using Subversion (The Pragmatic Starter Kit Series)(2nd Edition)
by Mike Mason

Read more about this title...

If you're an svn or tortoise junkie I recommend that you check out this book. Although most of the information provided in this book can probably be found in the SVN documentation, I much preferred reading this top to bottom. This book walks you through several different project scenarios and shows you how to effectively use svn as your source control system.

The appendices also offers a lot of very helpful information on setup and third party tools. Some must have tools for svn are:

  • TortoiseSVN
  • VisualSVN
  • SVN.exe

I love that visual svn takes care of things like moving files, add and deleting it really simplifies the check in process. Tortoise is a great windows explorer shell that provides a wicked abstraction over the svn shell.

Since reading the book I've found that I'm using tortoise less for checkin's and updates. Here's a couple of simple commands to get you started:

Update:

svnUp

Commit (check in):

svnci

One of the benefits about building with NAnt is being able to flip the switch and start targeting a different compiler, without having to switch to the latest version of Visual Studio. Although, you wont get the intellisense provided by studio for new features.

So today we flipped the switch on a project at work, from targeting the C# 2.0 compiler to the C# 3.0 compiler. We haven't started leveraging any of the new functionality available in the new compiler but at least we know we can start.

So to flip the switch you'll need to update your "nant.exe.config" file to include the .NET Framework version 3.5. Remember with this release we got a new version of the .NET Framework assemblies, a new C# 3.0 compiler but we're still running it all in the 2.0 version of the CLR.

The new xml element to add to your "Nant.exe.config" file looks something like this:

 1   <framework
 2       name="net-3.5"
 3       family="net"
 4       version="3.5"
 5       description="Microsoft .NET Framework 3.5"
 6       runtimeengine=""
 7       sdkdirectory="${path::combine(sdkInstallRoot, 'bin')}"
 8       frameworkdirectory="${path::combine(installRoot, 'v3.5')}"
 9       frameworkassemblydirectory="${path::combine(installRoot, 'v2.0.50727')}"
10       clrversion="2.0.50727">
11       <task-assemblies>
12           <!-- include .NET specific assemblies -->
13           <include name="tasks/net/*.dll" />
14           <!-- include .NET 2.0 specific assemblies -->
15           <include name="tasks/net/2.0/**/*.dll" />
16           <!-- include Microsoft.NET specific task assembly -->
17           <include name="NAnt.MSNetTasks.dll" />
18           <!-- include Microsoft.NET specific test assembly -->
19           <include name="NAnt.MSNet.Tests.dll" />
20       </task-assemblies>
21       <project>
22           <readregistry
23               property="installRoot"
24               key="SOFTWARE\Microsoft\.NETFramework\InstallRoot"
25               hive="LocalMachine" />
26           <readregistry
27               property="sdkInstallRoot"
28               key="SOFTWARE\Microsoft\.NETFramework\sdkInstallRootv2.0"
29               hive="LocalMachine"
30               failonerror="false" />
31       </project>
32       <tasks>
33           <task name="csc">
34               <attribute name="exename">csc</attribute>
35               <attribute name="supportsnowarnlist">true</attribute>
36               <attribute name="supportswarnaserrorlist">true</attribute>
37               <attribute name="supportskeycontainer">true</attribute>
38               <attribute name="supportskeyfile">true</attribute>
39               <attribute name="supportsplatform">true</attribute>
40               <attribute name="supportslangversion">true</attribute>
41           </task>
42           <task name="vbc">
43               <attribute name="exename">vbc</attribute>
44               <attribute name="supportsdocgeneration">true</attribute>
45               <attribute name="supportsnostdlib">true</attribute>
46               <attribute name="supportsnowarnlist">true</attribute>
47               <attribute name="supportskeycontainer">true</attribute>
48               <attribute name="supportskeyfile">true</attribute>
49               <attribute name="supportsplatform">true</attribute>
50               <attribute name="supportswarnaserrorlist">true</attribute>
51           </task>
52           <task name="jsc">
53               <attribute name="exename">jsc</attribute>
54               <attribute name="supportsplatform">true</attribute>
55           </task>
56           <task name="vjc">
57               <attribute name="exename">vjc</attribute>
58               <attribute name="supportsnowarnlist">true</attribute>
59               <attribute name="supportskeycontainer">true</attribute>
60               <attribute name="supportskeyfile">true</attribute>
61           </task>
62           <task name="resgen">
63               <attribute name="exename">resgen</attribute>
64               <attribute name="supportsassemblyreferences">true</attribute>
65               <attribute name="supportsexternalfilereferences">true</attribute>
66           </task>
67           <task name="al">
68               <attribute name="exename">al</attribute>
69           </task>
70           <task name="delay-sign">
71               <attribute name="exename">sn</attribute>
72           </task>
73           <task name="license">
74               <attribute name="exename">lc</attribute>
75               <attribute name="supportsassemblyreferences">true</attribute>
76           </task>
77           <task name="ilasm">
78               <attribute name="exename">ilasm</attribute>
79           </task>
80           <task name="ildasm">
81               <attribute name="exename">ildasm</attribute>
82           </task>
83       </tasks>
84   </framework>                 

To flip the switch you can either override the nant setting in your build file ...

1   <property name="nant.settings.currentframework" value="net-3.5" />

or you can change the default target framework in the "nant.exe.config" file.

1   <platform name="win32" default="net-3.5">

I can't steal the credit for figuring this out, I spent about an hour adding the new framework version to the Nant.exe.config file but the thing I missed was that there is no new version of the CLR. So Thank you Mr. Palermo!

Source Nant.exe.config

Can't we all just get a long? A couple weeks ago I was asked why I preferred using MbUnit over NUnit... and i realized the question kind of stumped me. Did I choose MbUnit or did I just start using because everyone else is?

So why do I like MbUnit? I think the first reason is this... I'm glad the Unit Runner support for MbUnit is limited. I know there's a plugin some where that allowed you to debug your MbUnit unit tests in version 2.* of JetBrains Unit Test Runner. But since 3.0 came out it's been difficult to do, and I'm kind of glad!

My dependence on the debugger is becoming less and less. Admittedly, in the current project I seem to be running the debugger more because of my on going battle with Crystal Reports, but that's another story. I've found that since I started using MbUnit, I've spent less time using the debugger and more time developing new functionality. At first there was definitely a stunt in development when learning to work without the debugger, but I'm getting better on not relying on it, and i feel good about it.

I like the MbUnit reports... you can take your pick of text, html, xml or dox. The text report is great for getting quick feedback to see if your tests have passed or if you need to walk through the stack trace to find out where tests have blown up. (Just give me the line #) I haven't completed figured out what the "dox" report type is supposed to be used for or if it has any relationship to "doxygen", a great documentation generation tool I used to use during my days of C development (Thank you Mr. Mark!). But I like the report that it generates. It writes out the names of the tests so that they read almost like plain English. Here's an example:

- merchandise,should_ have_ 1 0_ percent_ sales_ tax

In the above example, "merchandise" was the name of the class and "should_ have_ 1 0_ percent_ sales_ tax" is the name of the test. Pretty clear and easy to read, it definitely describes the intent of each test nicely!

Combining the "/sr" (show report) switch with a command line build and a readable report makes for some quick development and quick feedback. It's awesome when you can bang out code, run a build quickly and get quick descriptive response to help you.

Next up... I'm liking the "RowTest" attribute. When it comes to triangulating tests against your subject under test, this attribute can come back handy. Take this for example:

1   [RowTest]
2   [Row( 12.49 )]
3   [Row( 0.85 )]
4   [Row( 9.75 )]
5   public void Should_Calculate_0_Percent_Tax_On_Item( double forPrice ) {
6       AssertAreEqual( 0, CalculateTax( forPrice, ZeroPercent ) );
7   }

Instead of having to write out 3 different tests, or jamming the 3 different assertions into a single test, I can make use of the "RowTest" attribute to ensure my subject is behaving as I expect it to. Pretty nice!

Next up, the "Rollback" attribute... when you decorate your test method with this little attribute it rolls back any changes made to a database. This comes in quite handy for an integration test against a database. Now you can also make use of the TransactionScope type as while and roll out your own base class for data access tests, but I like that this is baked right in to the unit testing framework. Although, I admit I have not spent much time using this feature yet.

One of the cool new features in the latest version of NUnit is a new "That" method, which allows you write more readable assertions. For example:

1   Assert.That(new Money(expected), Is.EqualTo(actual));

Right now it seems that integrating NUnit with other tools like CruiseControl is much easier and supported more, since it is the de-facto standard for unit test frameworks, but spending time trying to figure out how to get MbUnit to get along with others tools help you to get a better understanding of how each tool works and how they work with others.

Either way, I can't say I'm biased to either MbUnit or NUnit. I think they're both great unit testing frameworks and I'm glad that they're around and free to use.

One of the easiest ways to protect your computer and speed up your Internet searches is to modify your "hosts" file. This file stores a list of domain names and corresponding IP addresses for those domains. So before your browser fires of a DNS query to see what "Google.com" current IP address is it first checks the host file to see if there is a record in their.

For more information check out Steve Gibson's write up on the subject.

There's an online group that maintains a list of potentially malicious sites, that you can add to your hosts file. So the next time you visit a site and it's trying to download a cookie for "doubleclick.net", it will get re-routed to localhost. (127.0.0.1). The first thing you will notice after updating your host file is the number of ads that no longer get displayed on web sites.

The current version of the hosts file updated by MVPS can be found here.

Your systems hosts file can be found...

  • Windows Vista = <System Root>\Windows\System32\Drivers\Etc
  • Windows XP = <System Root>\Windows\System32\Drivers\Etc

So by now a lot of you have probably already switched to GMail. But did you know that you can read your mail with an extra layer of privacy? The next time you log in to your gmail account, check the address bar to see if you're connected via SSL. If you're not then add the missing 'S' and click enter...

GmailHttps

There's a firefox plugin that I use that automatically switches you from HTTP to HTTPS. It's called "Customize Google" It add's a bunch of cool functionality like removing ads from your google searches, automatically using google suggest, blocking Google Analytics cookies.

CustomizeGoogle

Are you bored of the standard collections available in the .NET Framework? Are you looking to get more out of your collections? Well....

Ok enough of the info-mercial, so I came across the Wintellect's Power Collections Library and wanted to share. This library offers a bunch of different data structures that are not available in an out of the box .NET Framework install.

It's got collections like:

  • Deque
  • MultiDictionary
  • Bag
  • OrderedBag
  • OrderedDictionary
  • Set
  • OrderedSet
  • OrderedMultiDictionary

The library is now up on codeplex and the source is all available. Take a look... i just started digging, and I've got some ideas for my own home brewed collection.

I think Martin Fowlers description of optimistic and pessimistic locking is excellent. So excellent that I had to share...

"Let's suppose that Martin and David both want to edit the Customer file at the same time. With optimistic locking both of them can make a copy of the file and edit it freely. If David is the first to finish, he can check in his work without trouble. The concurrency control kicks in when Martin tries to commit his changes. At this point the source code control system detects a conflict between Martin's changes and David's changes. Martin's commit is rejected and it's up to him to figure out how to deal with the situation. With pessimistic locking whoever checks out the file first prevents anyone else from editing it. So if Martin is first to check out, David can't work with the file until Martin is finished with it and commits his changes." - Martin Fowler : PoEAA

SVN of course uses optimistic locking and Microsoft Visual Source Safe uses pessimistic locking. I've become a huge fan of SVN recently, and since we started using it here at work, I feel like I've become more productive. Gone are the days when I would hear

"Can you check in the project, I need to add a file." , "Where's <enter name>? He's not in today? But he's got a file checked out that I need."

Patterns of Enterprise Application Architecture by Martin Fowler Read more about this title...

There's a lot of cool things that you can do with nAnt, like running your tests against NUnit or another unit testing framework. Let's pretend we already have a target called "compile" that will compile our application into an assembly into the build folder. See...

We can create a new target that will compile our test project(s) into a single test assembly and save it to our build folder, where we saved our application assembly. The following target will recurse through a subdirectory called "test" and compile all files with a .cs extension into our test assembly.

    <target name="test.compile" depends="compile">
        <csc target="library" output="build\${project::get-name()}.Test.dll" debug="${debug}">
            <sources>
                <include name="src\test\**\*.cs" />
                <exclude name="src\test\**\AssemblyInfo.cs" />
            </sources>
            
            <references>
                <include name="build\${project::get-name()}.dll" />
                <include name="tools\nunit\bin\nunit.framework.dll" />
                <include name="tools\rhinomocks\Rhino.Mocks.dll" />
            </references>
        </csc>
      </target>    

The references element allows us to include other assemblies that our test assembly depends on. In the above case I'm using NUnit, and RhinoMocks. Our test assembly also depends on the application assembly, after all that is what our tests are supposed to be testing.

So far we have compiled our application assembly and test assembly, and saved them to the same directory called build. Now lets create a target that will run our unit tests using the nunit-console.exe.

    <target name="test" depends="test.compile">
        <copy todir="build" flatten="true">
            <fileset basedir="tools">
                <include name="**\Rhino.Mocks.dll" />
            </fileset>
        </copy>

        <copy todir="build" flatten="true">
            <fileset basedir="tools\nunit\bin">
                <include name="*.dll" />
            </fileset>
        </copy>
        
        <exec basedir="tools\nunit\bin" 
            useruntimeengine="true" 
            workingdir="build" 
            program="nunit-console.exe" 
            commandline="${project::get-name()}.Test.dll /xml=${project::get-name()}.Test-Result.xml" />        
    </target>

The above target will copy over the Rhino.Mocks.dll, and NUnit dlls into our build folder. Then execute "nunit-console.exe" from the command line and pass it in the path to our test assembly, and will tell it what to name the xml file that nunit will spit out with the test results.

As you can see the test results are also shown to the console window. As you can see, I have run 8 tests, with 3 failures. (Looks like I've made a breaking change!)

I've been spending some time trying to learn how to create builds using nAnt. You can use a special nAnt element to compile your .cs source files against the C# compiler.

  <target name="compile">
      <csc target="library" output="build\${project::get-name()}.dll" debug="${debug}">
          <sources>
              <include name="src\app\**\*.cs" />
              <exclude name="src\app\**\AssemblyInfo.cs" />
          </sources>                        
      </csc>
  </target>

The above target will compile all .cs files into a single assembly called .dll. (You specify your project name in the name attribute of the project element.)

  <project name="LogMyTime">

The compile target will recurse through all the files in a subdirectory called "src" and compile all the files with a .cs extension into the final assembly, excluding the AssemblyInfo.cs file (If you have multiple projects, each one will most likely have a different "AssemblyInfo.cs" file containing assembly info for that project.) The target will try to save the assembly to a folder called "build".

Before compiling you should ensure that the build folder exists. To do this you could create another nAnt target that creates the build directory. Here is an example.

  <target name="init">
      <mkdir dir="build" />
  </target>

We could now create a dependency between the compile target and the init target so that, the init target always runs before attempting to compile by adding the "depends" attribute.

  <target name="compile" depends="init"> ... </target>

Now we can run our nAnt task from the commandline:

The output will tell us what nAnt targets ran and if there were any compilation warnings or errors:

Related Resources:

Umbraco is open source .NET content management system. It's current release is version 2.1.6, and seems to look like if offers a better UI then some of the other content management systems. The demo shows you how to create pages and users and some other things.

You can check out the demos at http://umbraco.org/frontpage/demos.aspx

Umbraco needs .NET Framework 1.1, Microsoft SQL Server ( I used 2005 ) or MSDE. The target browsers are claimed to be:

  • Internet Explorer 5.5,
  • Firefox (no version specified, but I found it sucked on 2.0.0.4)
  • Safari

I was kind of impressed by the demo's but let down when I actually tried to install this guy and use it. When I tried to pull the source from the SVN server I received errors about to many locks and gave up. Maybe you'll have better luck: svn://svn.umbraco.org/var/lib/svn/Umbraco2.1

The Installation

I had a lot of problems installing Umbraco, I copied the full project after I downloaded it from here.

I created a folder in C:\inetpub\wwwroot\ called umbraco21 (C:\inetpub\wwwroot\umbraco21). I fired up inetmgr.exe, and changed the properties for this site to create an application. And specified ASP.NET version to 1.1.4322

 

 

 

 

 

I then opened up the web.config in notepad++, the documentation says that you have to change 4 keys in the config file:

  • umbracoReservedPaths
  • umbracoContentXML
  • umbracoStorageDirectory
  • umbracoPath

The original looks like:

1   <add key="umbracoReservedPaths" value="/umbraco/,/install"/>
2   <add key="umbracoContentXML" value="/data/umbraco.xml"/>
3   <add key="umbracoStorageDirectory" value="/data"/>
4   <add key="umbracoPath" value="/umbraco" />

I found the documentation didn't really describe what these really mean or how they were supposed to be used so I tried a few different variations before finally getting the installation wizard to start up properly. (Note: the forward slash at the start was very important!)

1     <add key="umbracoReservedUrls" value=",/umbracoTextGen.aspx,"/>
2     <add key="umbracoReservedPaths" value="/umbraco21/umbraco/,/umbraco21/install"/>
3     <add key="umbracoContentXML" value="/umbraco21/data/umbraco.xml"/>
4     <add key="umbracoStorageDirectory" value="/umbraco21/data"/>
5     <add key="umbracoPath" value="/umbraco21/umbraco" />

Next, I then fired up firefox and punched in http://localhost/umbraco21 into my browser, and got the Umbraco 2.1 Configuration Wizard!

 

When I pressed Next, I found that I was staring at "Directory Listing Denied" (take a look at the URI in the address bar!)

It appears that the install wizard tried to add a query string to the page and post back to itself, I had not specified a default document in my IIS configuration. So I went back and set "Default.aspx" as the default document!

The database setup was moderately simple, as long as the connection string is set properly in the web.config file.

At the end of the wizard I was told to add the following key to the web.config and to delete in the /install folder.

  <add key="umbracoConfigurationDone" value="211"/>

During the process you're asked to set a password for a default user, but it never told you what the default username was. I had to dig it out of the database but it's "umbraco".

Once I logged in I found that nothing seemed to render properly in Firefox.

 

If you start to dig into the source you'll see that it uses IFrames, and Frames in different sections of the Administrator section. Because of this I basically could not do anything in FireFox 2.0. So I tried Internet Explorer 7.0, when I did I kept receiving JavaScript warnings and saw the same thing. I could do anything with Umbraco... I suppose you could say my experience with Umbraco is a non-experience.

Re-building your database using nAnt!

Source Code:

Have you ever peeked into the SQL Server tools folder. I found a couple of interesting tools in there.

Both of these useful executables allow you to connect to a SQL Server. So using either of these executables and the power of nAnt, I can re-build a database from scratch.

  <?xml version="1.0"?>
  <project name="University" default="all">
      <!-- environment-specific properties -->
      <property name="sqlcmd.exe" value="C:\program files\microsoft sql server\90\Tools\Binn\sqlcmd.exe" />
      <property name="sqlcmd.ConnectionString" value="-E" /><!-- Windows Authentication -->            
      <property name="initial.catalog" value="University"/>
      <property name="initial.server" value="(local)" />
      <property name="database.path" value="C:\nant\databases" />    

      <target name="convert.template">
          <echo message="Convert the SQL file template to one with the actual database name." />
          <copy file="${target}.template" tofile="${target}" overwrite="true">
              <filterchain>
                  <replacetokens>
                      <token key="INITIAL_CATALOG" value="${initial.catalog}" />
                      <token key="DBPATH" value="${database.path}"/>
                  </replacetokens>
              </filterchain>
          </copy>
      </target>
      
      <target name="exec.sql.template">
          <call target="convert.template" />
          <echo message="Connecting to database server..." />
          <echo message="${sqlcmd.exe} ${sqlcmd.ConnectionString} -b -i ${target}" />
          <exec program="${sqlcmd.exe}" commandline="${sqlcmd.ConnectionString} -S ${initial.server} -b -i ${target}" />
      </target>    
      
      <target name="builddb">
          <copy todir="${database.path}">
              <fileset basedir="sql\original">
                  <include name="*"/>
              </fileset>
          </copy>
          <property name="target" value="sql\attach.sql"/>
          <call target="exec.sql.template"/>
      </target>                   

  </project>

In order to create the database you will have to update the properties in the build file to settings specific to your machine, then open a command window to the directory containing the build file and type "build builddb" then press enter.

Resources: * Sqlcmd.exe

Open ID is definitely an interesting concept. The basic premise is that you maintain a single Identity that you can use to verify who you are to different sites that support Open ID.

You identify yourself with a unique URI. To log in to a Open ID site you enter your Uri. The website should then re-direct you to your Open ID provider, where you provide your log in credentials to verify that it's actually you trying to claim to use this Open ID.

Here's a good screen cast on the topic Open ID screen cast.

There are several libraries written in different languages available to developers for use on their Open ID affiliate sites. Found here...

The one I tinkered with was Nerdbanks Open ID web control , which references JanRains Open ID library. The control was very simple to use and start using... the full source is available and released under a LGPL license.

I ran the Nerdbanks assembly against FxCop and found several things that could be improved on. Personally, I would want to fix a lot of these issues before using this myself, but it's nice to have a starting point to begin working with. The Nerdbanks assembly also contains a lot of extra code all bundled into a single assembly, again my personal preference would be to probably break out the "tools" from the "web controls" into separate assembly's.

Open ID seems like a pretty cool concept and it's nice to have libraries available to start with... anyways this just skims the surface of what Open ID is... but hopefully it's a good primer!