Sometimes the appropriate response to reality is to go insane - Philip K Dick RSS 2.0
 Monday, January 28, 2008

Today I wanted to setup JetBrains TeamCity as a pilot to run continuous integration for us.

With their new licencing model, TeamCity is free for up to 20 build configurations, 3 build agents and 20 users, which is more than enough for us to get going and see if it improves our process.

Other options were Team Foundation Build or CC.Net

Personally I discounted Team Build early, various comments on mailing lists and forums made it very clear that it was far from being a CI server out of the box, and although after some apparently extensive configuration it could be made to do something similar, it is far from a friction free piece of software.

CC.Net I have used a number of times before, but the XML configuration it requires is less than joyous, and no matter how often I set it up, I never seem to get quicker at it. Good it may be, easy to configure it isn't.

So we decided to start off with a clean Windows 2003 Server installation, as it comes out of the box. That meant that we didn't even install IIS, as TeamCity includes Tomcat to serve up its dashboard.

We had a few teething problems, but the installation was up and running inside a few short minutes ... albeit not building.

The first problem was rather major - under the VCS settings in TeamCity we had opted for Team Foundation Server, and given it all the settings we knew to be correct - but it repeatedly gave us an obscure error - one with no information other than a java exception:

jetbrains.buildServer.vcs.VcsException: TFS execution error
Stdout:
TFS Native Verifier v1.0 Copyright (C) 2006-2007 JetBrains s.r.o. by Mikhail Pilin and Eugene Petrenko
Stderr:
Exception:
at jetbrains.buildServer.buildTriggers.vcs.tfs.TfsNativeExeRunner.start(TfsNativeExeRunner.java:20)

We spent a fair while on this, eventually giving in and dropping an email to JetBrains - all credit to Serge there for a quick response. After a few confusing emails backwards and forwards, the first solution they could suggest was that I needed a "full TFS" install on the CI server.

This wasn't a great solution - we were deliberately trying to keep the server clean, the last thing I wanted was Visual Studio or Team Explorer installed.

After a bit of searching around, and some helpful hints on the altdotnet mailing list, I found that MS now package the Team Explorer as a download on its own. This looked after unpacking to install some kind of Visual Studio "light" which I still didn't want on the server - but after drilling down I found the Microsoft.TeamFoundation.xxxx assemblies were included in the package. I added these into the GAC, and the problem was instantly resolved without an install of Team Explorer or Visual Studio. A very short while afterwards a clarification came from JetBrains:

To be more specific, the following components must be in PATH:

Microsoft.TeamFoundation.Client.dll
Microsoft.TeamFoundation.Common.dll
Microsoft.TeamFoundation.Common.Library.dll
Microsoft.TeamFoundation.dll
Microsoft.TeamFoundation.VersionControl.Client.dll
Microsoft.TeamFoundation.VersionControl.Common.dll
Microsoft.TeamFoundation.VersionControl.Common.Integration.dll
Microsoft.TeamFoundation.WorkItemTracking.Client.Cache.dll
Microsoft.TeamFoundation.WorkItemTracking.Client.DataStore.dll
Microsoft.TeamFoundation.WorkItemTracking.Client.dll
Microsoft.TeamFoundation.WorkItemTracking.Client.Provision.dll
Microsoft.TeamFoundation.WorkItemTracking.Client.QueryLanguage.dll
Microsoft.TeamFoundation.WorkItemTracking.Client.RuleEngine.dll
Microsoft.TeamFoundation.WorkItemTracking.Proxy.dll

The GAC solution was therefore on the mark, but we may have got away with dropping the assemblies in the path too. Either way - this was a much cleaner install.

Our second problem was a silly mistake in configuring the project. We are using MSBuild to do the building, and we kept getting a "MSBuild Schema could not be found" error. After a lot of head bashing it turned out I had managed to click on the Validate option in TeamCity, and it was TeamCity rather than MSBuild that was throwing the error - TC could certainly do with better logging. The missing schema file could probably have been dropped alongside the .build file, but as we didn't need it to be validated, we unticked the option, and voila ... it all worked ... almost ...

One last little niggle caught us, NCover was timing out while running, and giving us an error regarding the profiler. We had included NCover in our TFS tree, along with NUnit, Rhino, and all the other tools we need, this was to avoid having to install anything on a workstation to be able to build the projects.

After a hint from Ayende, it turned out that NCover requires an assembly to be registered with regsvr32, something I haven't done in so long, I had forgotten the command even existed! So to solve this problem, the answer is:

regsvr32 coverlib.dll

It may not be ideal, but it does the job, and I think I can live with one assembly needing to be registered, at least in the short term.

Update: Grant Drake posted about this a while ago, and has 4 possible solutions here ... using //reg on the command line is a much better option in a CI environment, so I'm switching our build to do that this morning.

And with all that done, we now have a *very* clean CI server, running a very basic Windows Server install, with a very neat TeamCity install.

Now to show the business benefit!


Monday, January 28, 2008 6:32:32 PM (GMT Standard Time, UTC+00:00)  #    Comments [0] -
.NET | Agile | Code Coverage | Continuous Integration | Development | NCover | TeamCity | Testing
 Thursday, January 17, 2008

Previously I got my basic interception going, to allow me to strongly type resource requests.

The next step was to allow me to inject that capability via Windsor. The test for this was a bit tricky, due to me not understanding the Windsor container syntax in C#, but after a bit of playing around, we end up with the following code to create my IResource via the container.

    [TestFixture]
    public class SpikeProxyResources
    {
        [Test]
        public void TestWithFactoryCreation()
        {
            IWindsorContainer container = new WindsorContainer();
            FactorySupportFacility facility = new FactorySupportFacility();
            container.AddFacility("factory.support", facility);
            facility.AddFactory<IResource, ResourceFactory>("ResourceFactory", "CreateResource");

            IResource resource = container.Resolve<IResource>();
            Assert.AreEqual("GetVal", resource.GetVal);
            Assert.AreEqual("NewValue", resource.NewValue);

        }
    }

    public class ResourceFactory : IInterceptor
    {
        public IResource CreateResource()
        {
            ProxyGenerator generator = new ProxyGenerator();
            IResource proxy = generator.CreateInterfaceProxyWithoutTarget<IResource>(this);
            return proxy;
        }

        public void Intercept(IInvocation invocation)
        {
            if (invocation.Method.Name.StartsWith("get_"))
            {
                //TODO: Lookup resource here.... 
                invocation.ReturnValue = invocation.Method.Name.Substring(4);
            }
            else
                invocation.ReturnValue = null;
        }
    }

The next step will be to pull this configuration out into Xml ... or if I can convince the people that matter, into Binsor and Boo!

Thursday, January 17, 2008 5:43:55 PM (GMT Standard Time, UTC+00:00)  #    Comments [0] -
.NET | C# | Development | Sample Code
 Wednesday, January 16, 2008

Whilst discussing Globalization and Localization on the current SharePoint stuff I am working on, the issue of resource files, their location, their abstraction, and their general use came up.

One option was to use resgen.exe to create strongly typed classes for the resources, but I felt that this lost us the flexibility that dropping the .resx files into app_globalresources would provide us with.  Although accessing the compiled resources from the AppDomain is easy enough (look for an assembly called "app_GlobalResources"), we would then lose the strong typing, and have to resort to:

    ResourceManager rm = new ResourceManager(... ,...);
    rm.GetString("MyNonTypedName");

So to work around this I spent a bit of time looking into DynamicProxy2 from the Castle stack. After a few interesting diversions into the world of DictionaryAdapter (thanks to Ken Egozii and Josh Robb. Sadly poorly documented, but I'm sure it will prove invaluable soon), I finally came up with the simple bit of code I was trying to achieve:

    public class SpikeProxyResources
    {
        [Test]
        public void Test()
        {
            ProxyGenerator pg = new ProxyGenerator();

            IResource proxy = pg.CreateInterfaceProxyWithoutTarget<IResource>(new MyInterceptor());

            string s = proxy.GetVal;
            
            Assert.AreEqual("GetVal", s);

            Assert.AreEqual("NewValue", proxy.NewValue);
        }
    }

    public interface IResource
    {
        string GetVal { get;}

        string NewValue { get; }
    }

    public class MyInterceptor :IInterceptor
    {
        public void Intercept(IInvocation invocation)
        {
            if (invocation.Method.Name.StartsWith("get_"))
            {
                //TODO: Lookup resource here.... 
                invocation.ReturnValue = invocation.Method.Name.Substring(4);
            }
            else
                invocation.ReturnValue = null;
        }
    }

Fundamentally, this allows us to intercept the calls to the getter on IResource, and look up the resource we are after within the compiled resources. For the moment it may only return the called Method Name, but only because I saved you the boring bit that goes off and gets back the real value.

IResource can now be instantiated by Windsor and adding more strongly typed resources is just a matter of adding a get property onto the interface.

 

Wednesday, January 16, 2008 4:03:44 PM (GMT Standard Time, UTC+00:00)  #    Comments [0] -
.NET | Castle | Development | Sample Code
 Thursday, January 03, 2008

Whilst reading a great article on getter and setter methods, I came across a small quotation that perfectly encapsulated the problems I see with a lot of code at my current client: Developers by their nature have a desire to hang on to global data, and to create global methods.

In 1989, Kent Beck and Ward Cunningham taught classes on OO design, and they had problems getting people to abandon the get/set mentality. They characterized the problem as follows:

The most difficult problem in teaching object-oriented programming is getting the learner to give up the global knowledge of control that is possible with procedural programs, and rely on the local knowledge of objects to accomplish their tasks. Novice designs are littered with regressions to global thinking: gratuitous global variables, unnecessary pointers, and inappropriate reliance on the implementation of other objects.

This problem is particularly common where I am at present as a large part of the development work is in MOSS 2007, which encourages global data and methods in a large number of insidious ways.

I'm now off to re-read Beck and Cunningham in more detail ... but in the meantime, pretty please MS, could you stop encouraging bad practices!

 

Thursday, January 03, 2008 8:26:26 AM (GMT Standard Time, UTC+00:00)  #    Comments [1] -
.NET | Design | Development | MOSS 2007 | rants | SharePoint
 Friday, December 21, 2007

Early in the new year my current client has asked me to present to the senior management on two areas they feel they can currently improve in, their RUP project management process, and their development processes overall.

Attached are two presentations in their early form, in PowerPoint 2003 format.

Missing from the presentations are the notes (which I will add once I am happy with the overall structure) but you should be able to figure out what I am intending to say for each slide/bullet point.

Both of these presentations will evolve over the next few weeks. Feel free to comment either by the comment option or directly to me, and if you think they will be helpful to you for a presentation, also feel free to use them and modify them as you see fit.

Agile.ppt (80.5 KB)

This is intended to give a very high level view of Agile, to a group of senior managers who practice almost none of these things at present, and who are not 'tech savy'. This is fundamentally a 'get to know you' kind of presentation, to encourage aspects of Agile to be adopted, rather than any specific methodology or practice.

Development.ppt (80.5 KB)

This is intended to be presented to a similar level group, but the audience members may overlap to some degree with the previous presentation, and some may not. At the moment it is more likely that these people are closer to the ground and more 'tech focused'.

It is intended to give some key practices that can help improve the development processes the client currently has, again without forcing a wholesale shift to a specific Agile methodology on to them.

Oh, and Merry Xmas (or whichever thing you celebrate at this time of year!)

 

Friday, December 21, 2007 8:39:32 AM (GMT Standard Time, UTC+00:00)  #    Comments [4] -
Design | Agile | alt.net
 Wednesday, December 12, 2007

There are many forms of speed bump in development, things that cause you to slow down, stop, change your train of thought. From large things like people coming to your desk and asking questions, to smaller things like your IDE pausing for that half a second to refresh the screen. In fact if you think about your day, it is amazing how you get any work at all done with this many distractions and diversions.

But, to me, the most annoying of all these things is a poorly thought out IDE - after all I spend a lot of my time inside it, and that means a lot of my wasted time is caused by it too.

On the ALT.NET mailing list Frans Bouma suggested that most refactorings were small things that take less than a minute to do without a tool like ReSharper or Refactor.

To me - that is a speed bump - it is a minute I really shouldn't have to waste, just because I thought of a better way to structure a small part of my code. I don't think I have ever written a piece of code that was right first time, so pretty much I refactor everything I write to some lesser or greater degree.

Visual Studio is a great IDE, but it still has lots and lots of annoying things, and the refactoring it supports is pitiful. So for me, ReSharper is essential, it removes so many speed bumps from my daily path, that I can continue onwards and keep watching the road.

Technorati Tags: ,

Wednesday, December 12, 2007 9:02:08 AM (GMT Standard Time, UTC+00:00)  #    Comments [0] -
Development | rants | ReSharper
 Tuesday, December 11, 2007

Surely some mistake?

I write an Event Handler for SharePoint 2007, deriving from SPItemEventReceiver, and all is well. Until I try to put in some basic IoC using the Windsor container.

My thinking is that Windsor will allow me to separate the mechanism and plumbing of the Event Handler from the implementation of my nitty gritty stuff - and indeed it does - all is well and good. Until, that is, I decide to put the Windsor container where it really belongs, in the HttpApplication global scope.

My first try for testing this was :

if (HttpContext.Current.Application["WindsorContainer"] == null)
HttpContext.Current.Application["WindsorContainer"] = 
new WindsorContainer(new XmlInterpreter()); IWindsorContainer container =
(IWindsorContainer)HttpContext.Current.Application["WindsorContainer"];

Which was all well and good until my Event Handler just fell over ... so I stepped into debug mode ... and was beffudled ... there is no HttPContext.Current ... Nor is there any SPContext.Current either ...

This is confusing, and annoying ... my event is clearly working from an event on a list, which is clearly running within a web application, and within a SharePoint application. Apparently I'm not the first to discover this, but I haven't found a  solution yet ...  AAARRRRGGGHHHHHH!!!!!!!

 

Update: Oren and Ken both came up with similar suggestions on how to improve this situation specifically for Windsor, by putting a static class within the assembly that has the container within it. Certainly makes this a little more palatable from the Windsor point of view, but this isn't just a Windsor issue ... SharePoint really does enjoy making my life hell! :)

 

Tuesday, December 11, 2007 2:04:36 PM (GMT Standard Time, UTC+00:00)  #    Comments [2] -
Castle | rants | Sample Code | SharePoint | Testing
 Tuesday, December 04, 2007

Whilst browsing the blog of Serge van den Oever I came across some brillaint tools he links to ... and for my future reference ... here they are:

SharePoint 2007 'Attach to Debugger' menu item

Which then links to the CodePlex project where this lives

And a really cool EventsManager for lists and documents

Tuesday, December 04, 2007 11:55:11 AM (GMT Standard Time, UTC+00:00)  #    Comments [0] -
Development | SharePoint
 Monday, December 03, 2007

I am pleased to say, not only do I have a full working Model-View-Presenter implementation running within a SharePoint WebPart now, but I am very very close to having the rendering abstracted away from the WebPart and into a UserControl too. I'll blog more about this when I'm happy with the whole solution end to end.

In the meantime however, one annoying problem got me very very confused for a while ... if only SharePoint didn't give such stupid error messages and let you debug it properly, my life would have been much easier ... It was silly mistake really ... would have found it in 30 seconds in an ASP.NET application ... anyway I digress.

Remember, if you are using Castle Windsor from the GAC (as you need to for SharePoint work), then the web.config entry must specify the stong name of the assembly in the ConfigSections entry:

<section name="castle" 
type="Castle.Windsor.Configuration.AppDomain.CastleSectionHandler,
Castle.Windsor, Version=1.0.3.0,
Culture=neutral, PublicKeyToken=407dd0808d44fbdc" />

I had copied and pasted the entry from another project, not in the GAC, it only had the entry as Castle.Windsor and voila I got a lot of cryptic errors from SharePoint.

As a secondary note, remember all of your entries in the <castle> section must also specify the strong name, or they too will give you cryptic messages and a lot of wasted effort.

Another one to watch out for!

Monday, December 03, 2007 1:39:10 PM (GMT Standard Time, UTC+00:00)  #    Comments [1] -
C# | Castle | Development | rants | Sample Code | SharePoint

I have little idea why, but I have now encountered this a fair few times, so much so that I thought I might as well blog it, others must be getting it too.

If you are missing your 'Step Into' option from the Debug menu and toolbar in VS, there is a simple fix: Select Tools / Import and Export Settings from the menu, then select Reset All Settings and follow through the next parts of the wizard.

This should have your Debug menu items back, though you may have to fix some other things back to how they were (like fonts and colours). Also if you have ReSharper installed, you need to go to the ReSharper / Options menu and under the General section reset your ReSharper shortcuts there.

 

Monday, December 03, 2007 10:13:30 AM (GMT Standard Time, UTC+00:00)  #    Comments [0] -
.NET | Development | ReSharper
Navigation
Archive
<January 2008>
SunMonTueWedThuFriSat
303112345
6789101112
13141516171819
20212223242526
272829303112
3456789
About the author/Disclaimer

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

© Copyright 2008
Casey Charlton
Sign In
Statistics
Total Posts: 41
This Year: 13
This Month: 0
This Week: 0
Comments: 27
Themes
Pick a theme:
All Content © 2008, Casey Charlton
DasBlog theme 'Business' created by Christoph De Baene (delarou)