Showing posts with label development. Show all posts
Showing posts with label development. Show all posts

Friday, August 5, 2011

Software development career tip: Find yourself a mentor

A few weeks ago someone asked me the following question:

If I was to offer one piece of advice to someone considering becoming a software developer, what would it be?

At the time I answered that they should expect to never stop learning. Things in the software development world are always changing and if you stop learning you can easily stagnate.

Though I still consider that good advice if I'm asked that again I think I'll change my answer. My advice is simply:

Find yourself a mentor.

Usually a mentor will be a more senior developer, tester, agile coach etc within the company you work for. I know it's hard to ask for help, but don't be shy. Speak up and actively ask for mentoring.

I never had a software development or agile mentor. i.e. someone to take me under their wing, help point me in the right direction. I've mainly learnt everything by myself, via an occasional course and through talking to colleagues. That's not to say I don't value any of these methods, it's just I feel that being mentored accelerates learning.

After being a mentor to other developers, I've seen how quickly they've learnt techniques that I took many years to even discover and use properly. This plus their own self learning, eventually allows the student to surpass the master.

Though I've implicitly known this for years, I've only just recognised it and I recognise that I also could do with a mentor myself when it comes to coaching agile teams. I'm kind of using forums and social networking to fill this gap, but I don't feel like it's quite enough. If anyone wants to help me out let me know ;)

I sometimes wonder where I'd be if I had had a mentor throughout my career, but that sort of thinking is counter productive. Does it upset me? Not really, it's nice to see others build on the knowledge I've bestowed upon them. If I'm really honest I sometimes have a twinge of regret or jealousy, but it's fleeting and I'm only human.

What are your experiences in being a mentor or a mentee?

Friday, April 22, 2011

SSRS 2008 Quick tip: designing your databinding scheme for a custom charting control

So you've decided to create your own SSRS 2008 charting control. Good luck. The API is highly under-documented and there are very few examples out there. Now that I've got that disclaimer out of the way I'll proceed.

One of the decisions you'll have to make is how to structure your data for consumption by your control.

If your chart only needs a simple mapping scheme, where you consume data as it's returned by the dataset, then this tip won't matter much to you.

If you want to do something more complex then you'll be pleased to discover that any custom chart has similar column and row grouping capabilities that a standard tablix has.

Tip:

When getting your control databinding working create a tablix for debugging. This tablix should have the same grouping setup, including expressions, which also consumes the same dataset. This way you can debug any issues with the data you're receiving and also experiment with new grouping setups and expressions without wondering if there's a problem with your code.

I'm not going to go into great depth about the databinding code itselfu at this stage. I plan to do that in a future post.

Tuesday, March 1, 2011

Bug wrangling

Many teams have a hard time dealing with how to handle bugs no-matter what methodology they are using.
Teams who are generating a lot of bugs get overwhelmed by them eventually.  This is very stressful and demoralizing.

I've found that initial thoughts are generally around how to manage bugs them rather than why are we getting so many in the first place.  This leads to adoption of things such as bug tracking software, bug cards to be prioritized into future sprints or even a bug squashing sprint amongst others.  Unfortunately when you are in firefighting mode its hard to take a step back and look at fixing the cause rather than the symptoms.

Firstly you need to discover the reason(s) why you are generating so many bugs.

There are few ways to get that information. One way is to, as a team, do a root cause analysis on each bug that comes in.  Use something simple. I like the 5 why's technique.  From here you should be able to find out areas to focus on for a more detailed analysis.

You should also increase your bug transparency. Display your current bugs on cards as an information radiator on a wall, whiteboard etc. Using a tool hides the number of open bugs to a few people, having it on the wall makes it visible to everyone, potentially even customers.

When it comes to bug prioritization my rule of thumb is, make all bugs a priority over anything else.  If it's not high priority enough to do as a top priority, forget about it.

Your product owner should be able to help prioritize.

Traditionally bugs that don't warrant immediate fixing get logged in a bug tracking system and get forgotten about anyway. They get forgotten because they never become high enough priority over stories that generate business value. So why increase your signal to noise ratio.
 
Remember to talk about bugs at stand-up since the team needs to know the ad-hoc work not just project work.

... but I don't have time for this!!

So when will you have time?

If the answer is never then you have a bigger dysfunction(s) in the team. Too many bugs is probably a symptom of a larger problem (and out of the scope of this article). What are your team retrospectives telling you?

If the answer is in a few weeks then consider implementing some of the techniques above slowly. Perhaps only do root cause analysis on major bugs, or get the bugs up onto the wall and talk about them at stand-up.

I'd love to find out other peoples thoughts and perspectives on this issue.

Saturday, February 19, 2011

Quick tip: Linking against appropriate assembly depending on your configuration in VS.NET

Occasionally, while developing a .NET app, I've needed to reference an assembly from another solution from within my current one. Most often I see projects referencing either the debug or release versions directly, but what happens if you want to reference an assembly for the same configuration that your current solution is in? (i.e. referencing an external debug mode assembly while you're in debug mode and a release mode assembly in release mode)

The answer is an easy one, but can't be done directly by the IDE.

Reference the debug version of the  assembly you want to as per normal.

Next right click the project, which you just added the assembly to, and select edit project file. This will bring up the project's msbuild file.

Find the reference to the assembly you just added and replace the text Debug in the HintPath with $(Configuration)

Save and close the project file then reload the project. That's it! Now when you compile in debug or release mode the correct version of the referenced assembly will be compiled too.

NB: this assumes the dependant assemblies are located in Debug and Release folders off of the same parent folder.

Monday, July 12, 2010

ASP.NET MVC2 and the Enterprise Library Security Block Authorization Provider

When I first started with ASP.NET 2.0 I was intrigued by the built-in support for users and roles via the Membership Providers. Unfortunately I quickly found limitations for its use mainly due to the way that I like to structure permissions in my applications.

I overcame some of these limitations by using the Enterprise Library Security block which allowed me to set granular permissions and then roll them up into groups of permissions which map to individual roles.

I recently switched over from ASP.NET, using the MVP pattern, to ASP.NET MVC2 and again found the the way roles are mapped to be too limiting. Therefore I decided to implement my own custom AuthorizeAttribute to check for specific authorization rules using the Enterprise Library Security block.

This article assumes that you know how to use Membership and Role providers in ASP.NET and that we have a role called Administrators already configured. If you aren't familiar with these I'd suggest looking at the following article:

Examining ASP.NET's Membership, Roles, and Profile

I also assume that you know how to use the MVC2 authorization model.

The first thing to do is add a reference to the following assemblies in your MVC project:

Microsoft.Practices.EnterpriseLibrary.Security
Microsoft.Practices.EnterpriseLibrary.Security.Configuration
Microsoft.Practices.EnterpriseLibrary.Common

Next we'll have to configure the security block in the web.config. I'm also going to create a authorization rule which maps a "Can Manage Users" permission into the Administrators role.
<configuration>
<configSections>
<section name="securityConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Security.Configuration.SecuritySettings, Microsoft.Practices.EnterpriseLibrary.Security, Version=4.1.0.0" />
...
</configSections>
<securityConfiguration defaultAuthorizationInstance="RuleProvider" defaultSecurityCacheInstance="">
<authorizationProviders>
<add type="Microsoft.Practices.EnterpriseLibrary.Security.AuthorizationRuleProvider, Microsoft.Practices.EnterpriseLibrary.Security" name="RuleProvider">
<rules>
<add expression="R:Administrators" name="Can See Admin Menu" />
</rules>
</add>
</authorizationProviders>
</securityConfiguration>

Next we have to create our custom AuthorizeAttribute. This will allow us to check against the Enterprise Library Security block. We can do this by inheriting from the standard AuthorizeAttribute and overriding the AuthorizeCore method.
  public class AuthorizeRule : AuthorizeAttribute
{
public string Rule { get; set; }

protected override bool AuthorizeCore(HttpContextBase httpContext)
{
if (string.IsNullOrEmpty(Rule))
{
throw new InvalidOperationException("Rule not specified");
}

if (!httpContext.User.Identity.IsAuthenticated)
{
return false;
}

IAuthorizationProvider auth = AuthorizationFactory.GetAuthorizationProvider();
return auth.Authorize(httpContext.User, Rule);
}
}

Finally we mark up the appropriate controller method that you want to secure just as we would using the AuthorizeAttribute.
[AuthorizeRule(Rule = "Can Manage Users")]
public void Index()
{
...
}

It's as easy as that.

Friday, July 2, 2010

When should software be rewritten

Over the last 14 years of my professional software development career, I have often heard developers complain about their existing code-base (including me). These complaints are generally along the same themes; how it has become difficult to maintain; that the code has become a big ball of mud; that changing code causes ripple effects; that no-one likes to touch module X because its so brittle; it takes new developers a long time to get up to speed with the code etc etc.

Normally the team consensus is that the product should be rewritten from the ground up. The idea is that this will sort out all of the design issues that are in the current version, it'll be more maintainable & more stable.

So the team embarks on this quest all the while management still wants new features and bug fixes to the existing version. This causes the original code-base to become a moving target causing the rewrite to take longer. This also ties up resources that could be working on new features, moving the product forward and adding value to the business.

In my experience the only time to rewrite a code-base is when moving to a new platform or technology. For example moving from Winforms to WPF. A rewrite is normally a lengthy and costly affair which rarely ends up with the clean design that was sought. New bugs are introduced which aren't covered by existing regression tests.

Rather than rewriting the entire application, the strategy I would recommend is to refactor it.

To get the most benefit from refactoring a code base, you'll need to increase testability. This will involve moving to a more loosely coupled design. I've chosen to use Behaviour Driven Design (BDD) which is an extension of Test Driven Design (TDD). Though you could bolt on tests after code but I wouldn't recommend that for many reasons which I won't go into here.

I have found that provided your code is loosely coupled and designed for testability, you are able to move towards an incremental design model in which developers can feel confident making changes and with greater speed.

So what happens if you have a tightly coupled application which might be tested by a QA team but doesn't have any unit tests?

Over the next few articles I'll be outlining some strategies for refactoring your legacy ASP.NET apps

Wednesday, March 3, 2010

Calculating when a MultiScaleImage has reached 1:1 scale of the original image.

For a project I am working on I'm using a Silverlight MultiScaleImage to display an exceptionally large tiled image. As part of this I wanted to enforce a maximum zoom when the image was displayed at 1:1 scale. After some Googling I wasn't able to find any immediate solutions so I had to tackle it myself.

The solution I came up with in the end was fairly simple. I already had the original image width in pixels, so all I had to do was to compare that against MultiScaleImage.ActualWidth divided by MultiScaleImage.ViewportWidth before zooming.

e.g.

if(_msi.ActualWidth / _msi.ViewportWidth > OriginalImageWidth)
{
return;
}
_msi.ZoomAboutLogicalPoint(...

Note: I'm still pretty new to the MultiScaleImage so if there's a better way feel free to comment.

Friday, January 15, 2010

Migrating relational data into a SQL Server XML datatype column

Recently I needed to take the data from a SQL Server table, convert it into XML and insert it into an xml datatype column of a related table. In the past I would have used a scripting language such as Perl to achieve this, but since SQL Server 05/08 has native XML support I decided to give that a go.  I did this because I thought it would be more efficient, and less error prone, to do everything at the database level. It turns out that it was easier than I thought.

I was already familiar with SELECT .. FOR XML syntax from previous experiments with SQL Server's XML functionality, so was able to convert the existing table data to XML as follows:
SELECT part_id, part_name, part_description
FROM parts FOR XML AUTO, ELEMENTS
This generated the following XML:
<parts>
<part_id>4</part_id> 
  <part_name>Widget</part_name>
  <part_description>Widget to do something</part_description>
</parts>
Note: The XML generated by FOR XML AUTO was good enough for my purposes. If you need more control over the XML output you can use FOR XML EXPLICIT instead.

The next step was to insert this into the appropriate row of a related table. I achieved this using a sub-query on an UPDATE.  The resulting SQL was as follows:
UPDATE orders SET bio_sample_aliquot_info = ( 
SELECT part_id, part_name, part_description FROM parts 
WHERE order.id = part.order_id FOR XML AUTO, ELEMENTS)
FROM orders
Normally I don't like using sub-queries as they can be inefficient, but this ended up been fast enough for my needs.

After running the above query I had the XML I wanted in the appropriate XML datatype rows of the related table.

Note: I've changed all of the names of the tables and columns in the example above.  Also I tested this on SQL Server 08, but not 05.

Tuesday, November 24, 2009

Occassional VS.NET 2008 lockup on build

A few weeks ago I started having sleep and shutdown issues with my development machine which was running Windows XP. Faced with the prospect of having to re-image the machine I decided to bite the bullet and install the Windows 7 Enterprise disk that we had recently received from Microsoft.

I've been very impressed with Windows 7 and now prefer it to XP, but I did start getting occasional lockups when building DLLs in VS.NET 2008. When these lockups occurred the only way I could kill the devenv.exe process was to logout.

At first, after doing some initial searches on the issue, I assumed this was just a Windows 7 problem that I'd have to ignore until VS.NET 2010 was released or Windows 7 SP1. Today I decided that enough was enough and proceeded to find a solution, which turned out to be pretty easy.

The problem was with the AVG 9 resident shield process (avgrsx.exe) which was trying to scan DLLs as VS.NET copied them. This was causing avgrsx.exe use 50% CPU and to lock Visual Studio. After killing this process VS.NET came back to life and continued building my project. To fix this conflict I opened the resident shield settings and put in an exception for my VS.NET projects root directory.

Though this was an easy fix I didn't spot it right away due to the differences in the way Task Manager works in XP and 7. On XP I was used to always seeing all processes from all users, but on Windows 7 I have to click the "Show processes from all users" every single time. This is a minor annoyance, but not enough to turn me off of Windows 7.