.hgignore file for IntelliJ IDEA Development

Every time I start a new project in Visual Studio, I almost always put it under Mercurial source control – even a small demo project.  If the project becomes serious enough, I’ll create a private repository in Bitbucket and maintain it there.  After I initialize my Mercurial repository, the first thing I do is grab Nino’s .hgignore file for Visual Studio.  It’s a great time-saver.

I’ve been playing around with Android development a bit lately using JetBrains IntelliJ IDEA 10.  Like my Visual Studio projects, I also create a local Mercurial repository for my Android code.  But since I’m new to Android development, there were a bunch of files (other than the source code I was writing!) and I didn’t know if these should be stored in my source code control system or not.

Luckily, JetBrains has a KB article on the subject: How to manage IDEA projects under Version Control Systems.  Using this info, I’ve created a stock .hgignore file I use for all of my Android projects.  Here’s the contents:

glob:.idea/workspace.xml
glob:.idea/tasks.xml
glob:out/*

I hope this useful for you.  If you know of any changes I could make, let me know!

Technorati Tags: ,,

Posted by PSteele | with no comments
Filed under: , ,

Automapper: Handling NULL members

A question about null members came up on the Automapper mailing list.  While the problem wasn’t with Automapper, investigating the issue led to an interesting feature in Automapper.

Normally, Automapper ignores null members.  After all, what is there really to do?  Imagine these source classes:

public class Source
{
    public int Data { get; set; }
    public Address Address { get; set; }
}
 
public class Destination
{
    public string Data { get; set; }
    public Address Address { get; set; }
}
 
public class Address
{
    public string AddressType { get; set; }
    public string Location { get; set; }
}

And imagine a simple mapping example with these classes:

Mapper.CreateMap<Source, Destination>();
 
var source = new Source
                {
                    Data = 22,
                    Address = new Address
                                {
                                    AddressType = "Home",
                                    Location = "Michigan",
                                },
                };
 
var dest = Mapper.Map<Source, Destination>(source);

The variable ‘dest’ would have a complete mapping of the Data member and the Address member.

But what if the source had no address?

Mapper.CreateMap<Source, Destination>();
 
var source = new Source
{
    Data = 22,
};
 
var dest = Mapper.Map<Source, Destination>(source);

In that case, Automapper would just leave the Destination.Address member null as well.  But what if we always wanted an Address defined – even if it’s just got some default data?  Use the “NullSubstitute” option:

Mapper.CreateMap<Source, Destination>()
    .ForMember(d => d.Address, o => o.NullSubstitute(new Address
                                                         {
                                                             AddressType = "Unknown",
                                                             Location = "Unknown",
                                                         }));
 
var source = new Source
{
    Data = 22,
};
 
var dest = Mapper.Map<Source, Destination>(source);

Now, the ‘dest’ variable will have an Address defined with a type and location of “Unknown”.  Very handy!

Technorati Tags: ,,
Posted by PSteele | 1 comment(s)
Filed under: ,

Moving a local Mercurial Repository to Bitbucket

I recently got a new laptop.  Part of the migration process was to move a few local Mercurial repositories into Bitbucket.  Since these are just “playing around” repositories, they’ll be private, but the beauty of Bitbucket is that you get unlimited private repositories.  This allows me to keep all of my little pet projects “up in the cloud” and it’s one less thing to migrate the next time I get a new machine.

The process couldn’t be simpler:

1. Log in to your Bitbucket account.

2. Under “Repositories”, select “Create New Repository”.

3. Enter the details for your repository.  Make sure you check the “Private” checkbox if you want this private.

Once your new repository is created, grab the URL (either the HTTPS one or the SSH one – depending on what you’re using) and copy it to the clipboard.  Now go to your local mercurial repository and enter:

hg push [repositoryURL]

Where [repositoryURL] will be the URL of your new repository (that’s why you copied it to the clipboard!).

The one last thing you’ll want to do is change the default path to your repository to be the Bitbucket repository.  So the next time you need to push changes up to Bitbucket, it will know where to go.  To do this, edit the “hgrc” file located in the .hg directory of your repository.  If there’s not a “[paths]” section, add one and then add a “default” key with the URL of your new repository (again, the clipboard comes in handy!):

[paths]
default = https://...

Done!

Technorati Tags: ,
Posted by PSteele | with no comments
Filed under: ,

Changing the Default Install Location of an MSI

A few months ago, I had to tweak an MSI installer.  It was installing into a specific directory (named the same as the application) underneath Program Files.  Since the location of Program Files can change from machine to machine, the MSI has a special token you can use for Program Files (as well as for the application name).  So the current value for “DefaultLocation” of the Application Folder was:

[ProgramFilesFolder]\[ProductName]

During installation, these tokens would be replaced by the actual location based on the current machine.

I needed to change this to a specific folder underneath the users My Documents directory.  I poked around the help file and I could not find where these special tokens (like “[ProgramFilesFolder]”) were defined.  Obviously, there must be some specific set of values that are available and I’m sure My Documents is one of them.

I finally found them documented so I’m posting the link here.  Hopefully, it will help someone else out.  Not sure where I found this link…

System Folder Properties

For me, it was as easy as changing the DefaultLocation to:

[PersonalFolder]\MyToolName\Application

Technorati Tags: ,

UPDATE: Finding the DefaultLocation property.

Posted by PSteele | with no comments
Filed under:

Setting up Windows Live Writer for Weblogs.asp.net

Once again, I’m on a new laptop and have forgotten how to set up Windows Live Writer to post to my Weblogs.asp.net account.  Thanks to Bil Simser, I’m up and running now.

I’ve found that a number of applications these days allow you to “export” your settings (FileZilla, Firefox plugins, bookmarks, etc…).  I think more companies should be doing this.  It makes migrating to a new machine a whole lot easier!

Posted by PSteele | with no comments

Using Lambdas for return values in Rhino.Mocks

In a recent StackOverflow question, someone showed some sample code they’d like to be able to use.  The particular syntax they used isn’t supported by Rhino.Mocks, but it was an interesting idea that I thought could be easily implemented with an extension method.

Background

When stubbing a method return value, Rhino.Mocks supports the following syntax:

dependency.Stub(s => s.GetSomething()).Return(new Order());

The method signature is generic and therefore you get compile-time type checking that the object you’re returning matches the return value defined by the “GetSomething” method.

You could also have Rhino.Mocks execute arbitrary code using the “Do” method:

dependency.Stub(s => s.GetSomething()).Do((Func<Order>) (() => new Order()));

This requires the cast though.  It works, but isn’t as clean as the original poster wanted.  They showed a simple example of something they’d like to see:

dependency.Stub(s => s.GetSomething()).Return(() => new Order());

Very clean, simple and no casting required.  While Rhino.Mocks doesn’t support this syntax, it’s easy to add it via an extension method.

The Rhino.Mocks “Stub” method returns an IMethodOptions<T>.  We just need to accept a Func<T> and use that as the return value.  At first, this would seem straightforward:

public static IMethodOptions<T> Return<T>(this IMethodOptions<T> opts, Func<T> factory)
{
    opts.Return(factory());
    return opts;
}

And this would work and would provide the syntax the user was looking for.  But the problem with this is that you loose the late-bound semantics of a lambda.  The Func<T> is executed immediately and stored as the return value.  At the point you’re setting up your mocks and stubs (the “Arrange” part of “Arrange, Act, Assert”), you may not want the lambda executing – you probably want it delayed until the method is actually executed and Rhino.Mocks plugs in your return value.

So let’s make a few small tweaks:

public static IMethodOptions<T> Return<T>(this IMethodOptions<T> opts, Func<T> factory)
{
    opts.Return(default(T));    // required for Rhino.Mocks on non-void methods
    opts.WhenCalled(mi => mi.ReturnValue = factory());
    return opts;
}

As you can see, we still need to set up some kind of return value or Rhino.Mocks will complain as soon as it intercepts a call to our stubbed method.  We use the “WhenCalled” method to set the return value equal to the execution of our lambda.  This gives us the delayed execution we’re looking for and a nice syntax for lambda-based return values in Rhino.Mocks.

Posted by PSteele | 1 comment(s)
Filed under: , ,

Xml Serialization and the [Obsolete] Attribute

I learned something new today: Starting with .NET 3.5, the XmlSerializer no longer serializes properties that are marked with the Obsolete attribute.  I can’t say that I really agree with this.  Marking something Obsolete is supposed to be something for a developer to deal with in source code.  Once an object is serialized to XML, it becomes data.  I think using the Obsolete attribute as both a compiler flag as well as controlling XML serialization is a bad idea.

In this post, I’ll show you how I ran into this and how I got around it.

The Setup

Let’s start with some make-believe code to demonstrate the issue.  We have a simple data class for storing some information.  We use XML serialization to read and write the data:

public class MyData
{
    public int Age { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public List<String> Hobbies { get; set; }
 
    public MyData()
    {
        this.Hobbies = new List<string>();
    }
}

Now a few simple lines of code to serialize it to XML:

static void Main(string[] args)
{
    var data = new MyData
                   {
   FirstName = "Zachary", 
                    LastName = "Smith", 
                    Age = 50, 
                    Hobbies = {"Mischief", "Sabotage"},
                   };
    var serializer = new XmlSerializer(typeof (MyData));
    serializer.Serialize(Console.Out, data);
    Console.ReadKey();
}

And this is what we see on the console:

<?xml version="1.0" encoding="IBM437"?>
<MyData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Age>50</Age>
  <FirstName>Zachary</FirstName>
  <LastName>Smith</LastName>
  <Hobbies>
    <string>Mischief</string>
    <string>Sabotage</string>
  </Hobbies>
</MyData>

 

The Change

So we decided to track the hobbies as a list of strings.  As always, things change and we have more information we need to store per-hobby.  We create a custom “Hobby” object, add a List<Hobby> to our MyData class and we obsolete the old “Hobbies” list to let developers know they shouldn’t use it going forward:

public class Hobby
{
    public string Name { get; set; }
    public int Frequency { get; set; }
    public int TimesCaught { get; set; }
 
    public override string ToString()
    {
        return this.Name;
    }
}
public class MyData
{
    public int Age { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    [Obsolete("Use HobbyData collection instead.")]
    public List<String> Hobbies { get; set; }
    public List<Hobby> HobbyData { get; set; }
 
    public MyData()
    {
        this.Hobbies = new List<string>();
        this.HobbyData = new List<Hobby>();
    }
}

Here’s the kicker: This serialization is done in another application.  The consumers of the XML will be older clients (clients that expect only a “Hobbies” collection) as well as newer clients (that support the new “HobbyData” collection).  This really shouldn’t be a problem – the obsolete attribute is metadata for .NET compilers.  Unfortunately, the XmlSerializer also looks at the compiler attribute to determine what items to serialize/deserialize.  Here’s an example of our problem:

static void Main(string[] args)
{
    var xml = @"<?xml version=""1.0"" encoding=""IBM437""?>
<MyData xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"">
<Age>50</Age>
<FirstName>Zachary</FirstName>
<LastName>Smith</LastName>
<Hobbies>
<string>Mischief</string>
<string>Sabotage</string>
</Hobbies>
</MyData>";
    var serializer = new XmlSerializer(typeof(MyData));
    var stream = new StringReader(xml);
    var data = (MyData) serializer.Deserialize(stream);
 
    if( data.Hobbies.Count != 2)
    {
        throw new ApplicationException("Hobbies did not deserialize properly");
    }
}

If you run the code above, you’ll hit the exception.  Even though the XML contains a “<Hobbies>” node, the obsolete attribute prevents the node from being processed.  This will break old clients that use the new library, but don’t yet access the HobbyData collection.

The Fix

This fix (in this case), isn’t too painful.  The XmlSerializer exposes events for times when it runs into items (Elements, Attributes, Nodes, etc…) it doesn’t know what to do with.  We can hook in to those events and check and see if we’re getting something that we want to support (like our “Hobbies” node).

Here’s a way to read in the old XML data with full support of the new data structure (and keeping the Hobbies collection marked as obsolete):

static void Main(string[] args)
{
    var xml = @"<?xml version=""1.0"" encoding=""IBM437""?>
<MyData xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"">
<Age>50</Age>
<FirstName>Zachary</FirstName>
<LastName>Smith</LastName>
<Hobbies>
<string>Mischief</string>
<string>Sabotage</string>
</Hobbies>
</MyData>";
    var serializer = new XmlSerializer(typeof(MyData));
    serializer.UnknownElement += serializer_UnknownElement;
    var stream = new StringReader(xml);
    var data = (MyData)serializer.Deserialize(stream);
 
    if (data.Hobbies.Count != 2)
    {
        throw new ApplicationException("Hobbies did not deserialize properly");
    }
}
 
static void serializer_UnknownElement(object sender, XmlElementEventArgs e)
{
    if( e.Element.Name != "Hobbies")
    {
        return;
    }
 
    var target = (MyData) e.ObjectBeingDeserialized;
    foreach(XmlElement hobby in e.Element.ChildNodes)
    {
        target.Hobbies.Add(hobby.InnerText);
        target.HobbyData.Add(new Hobby{Name = hobby.InnerText});
    }
}

As you can see, we hook in to the “UnknownElement” event.  Once we determine it’s our “Hobbies” node, we deserialize it ourselves – as well as populating the new HobbyData collection.  In this case, we have a fairly simple solution to a small change in XML layout.  If you make more extensive changes, it would probably be easier to do some custom serialization to support older data.

A sample project with all of this code is available from my repository on bitbucket.

Technorati Tags: ,,
Posted by PSteele | 1 comment(s)
Filed under:

Welcome 2011

About this time last year, I wrote a blog post about how January of 2010 was almost over and I hadn’t done a single blog post.  Ugh…  History repeats itself.

2010 in Review

If I look back at 2010, it was a great year in terms of technology and development:

  • Visited Redmond to attend the MVP Summit in February.  Had a great time with the MS product teams and got to connect with some really smart people.
  • Continued my work on Visual Studio Magazine’s “C# Corner” column.  About mid-year, the column changed from an every-other-month print column to an every-other-month print column along with bi-monthly web-only articles.  Needless to say, this kept me even busier and away from my blog.
  • Participated in another GiveCamp!  Thanks to the wonderful leadership of Michael Eaton and all of his minions, GiveCamp 2010 was another great success.  Planning for GiveCamp 2011 will be starting soon…
  • I switched to DVCS full time.  After years of being a loyal SVN user, I got bit by the DVCS bug.  I played around with both Mercurial and Git and finally settled on Mercurial.  It’s seamless integration with Windows Explorer along with it’s wealth of plugins made me fall in love.  I can’t imagine going back and using a centralized version control system.
  • Continued to work with the awesome group of talent at SRT Solutions.  Very proud that SRT won it’s third consecutive FastTrack award!
  • Jumped off the BlackBerry train and enjoying the smooth ride of Android.  It was time to replace the old BlackBerry Storm so I did some research and settled on the Motorola DroidX.  I couldn’t be happier.  Android is a slick OS and the DroidX is a sweet piece of hardware.  Been dabbling in some Android development with both Eclipse and IntelliJ IDEA (I like IntelliJ IDEA a lot better!).

 

2011 Plans

On January 1st I was pleasantly surprised to get an email from the Microsoft MVP program letting me know that I had received the MVP award again for my community work in 2010.  I’m honored and humbled to be recognized by Microsoft as well as my peers!

I’ll continue to do some Android development.  I’m currently working on a simple app to get me feet wet.  It may even makes it’s way into the Android Market.

I’ve got a project that could really benefit from WPF so I’ll be diving into WPF this year.  I’ve played around with WPF a bit in the past – simple demos and learning exercises – but this will give me a chance to build an entire application in WPF.  I’m looking forward to the increased freedom that a WPF UI should give me.

I plan on blogging a lot more in 2011!

Technorati Tags: ,,,,,
Posted by PSteele | with no comments

Guaranteed order in a foreach loop

I was always under the impression that the order items are returned via a foreach loop is not guaranteed.  For the most part, that is correct.  However, it’s not 100%.

I was working on some code today and there was a regular for loop that Resharper offered to convert to a foreach loop.  The for loop was moving through an array one item at a time (starting at zero).  Since I (incorrectly) assumed the order for a foreach loop was not guaranteed, I was surprised by Resharper’s suggestion.

So I decided to check the C# spec and see what it had to say.  Sure enough, I was wrong!  Check out section 8.8.4 on the foreach statement.  There’s this following tidbit:

The order in which foreach traverses the elements of an array is as follows: For single-dimensional arrays, elements are traversed in increasing index order, starting with index 0 and ending with index Length – 1. For multi-dimensional arrays, elements are traversed such that the indices of the rightmost dimension are increased first, then the next left dimension, and so on to the left.

So Resharper was right.  I changed the code and its much cleaner and easier to read!

Posted by PSteele | with no comments
Filed under: ,

EDAMLibrary : Evernote Library for C#

I recently pushed a library onto bitbucket.  It’s used for integrating with the popular note-taking, cloud-syncing, capture application Evernote.  I started using Evernote in February of this year and I’m addicted to it now.  I scan and tag tons of information and have it easily available at all times.  My data is sync’d to the cloud and accessible via a Windows client, the web and various mobile platforms (Blackberry, iPhone, Android).

While Evernote provides an API for accessing the data, it has a few organization issues that need to be overcome before you can use it.  To make it easier for those just wanting to play around with Evernote, I combined everything provided by Evernote into a single library.

And remember, if you want to develop something that integrates with Evernote, you’ll have to request an API key.  It’s a pretty simple process that just takes a few minutes.

Technorati Tags: ,,,
Posted by PSteele | 1 comment(s)
Filed under: ,
More Posts « Previous page - Next page »