Blogs

  • FOSDEM Videos Online 2

    I’ve been watching more FOSDEM videos. They are very cool. Watching in 720p is awesome. Alan McGovern on The Evolution of MonoTorrent – By far the best bittorrent library for .net. Alan talks about the challenges of writing a library that will handle things like hundreds (if not thousands) of simultaneous socket connections, why using threads [...]
  • FOSDEM Videos online

    As a .NET programmer in my day job targeting Windows desktop applications (winforms and wpf), I don’t get to stay on top of much ASP.NET or Mono. The ASP.NET stuff I feel like I have a good enough handle on via channels I use to stay on top of .NET in general (user groups, blogs, [...]
  • Flattening a Jagged Array with LINQ

    Today I had to flatten a jagged array .  In my case, it was a string[][] and I needed to make sure every single string contained in that jagged array was set to something (non-null and non-empty).  LINQ made the flattening very easy.  In fact, I ended up making a generic version that I could use to flatten any type of jagged array (assuming it's a T[][]): private static IEnumerable<T> Flatten<T>(IEnumerable<T[]> data) { return from r in data from c in r select c; } Then, checking to make sure the data was valid, was easy: var flattened = Flatten(data); bool isValid = !flattened.Any(s => String.IsNullOrEmpty(s)); You could even use method grouping and reduce the validation to: bool isValid = !flattened.Any(String.IsNullOrEmpty); Technorati Tags: .NET , LINQ , Jagged Array
  • Windows 7 mp3 tag editor

    I just accidentally found Windows 7’s built in mp3 (and presumably other metadata, exif perhaps) tag editor. I looked for this thing for what felt like hours over the past year. Eventually I sucked it up and downloaded mp3tag, but its still nice to know that this is there for the next time. Normally when browsing my [...]
  • LINQ Abuse with the C# 4 dynamic type

    With C# 4 adding some support for dynamic typing one of the first thing that I wanted to do is use it with LINQ. I want to do this: dynamic x; var h = from y in x where y == 1 select y.something; But I get error messages on both where and select [...]
  • Ignite 3 and several user group meetings this week

    Don't miss Ignite 3 . This is global Ignite week, so Ignite events are being held all over the country. Ann Arbor holds its 3rd Ignite event on Thursday, March 4 at the Ross School of Business, 701...
  • No Intellisense in Visual Studio 2010 RC1

    Well, that's odd.  Why were the default options for Intellisense turned off when I did a fresh install of Visual Studio 2010 RC1? Technorati Tags: .NET , Visual Studio 2010 RC
  • Note to Self 13 – Whole Lot of Django

    Testing Django can be somewhat challenging. Instead of simply running a unittest module, you need to run the manage.py script in your Django app passing it the “test” parameter. This sets up a test database...
  • Version Control Tools Is More Than Just The Tools

    Martin Fowler has an excellent post on Version Control, and he almost got all of the way there, but for more than just a tiny development shop I think he missed a few important pieces. http://martinfowler.com/bliki/VersionControlTools.html Martin does say that Mercurial and git get most of the attention and that the choice between the two come down [...]
  • Lookups vs. Dictionaries

    Donn Felker has a great post that explains the different uses of LINQ's ToLookup and ToDictionary .  Check it out! Technorati Tags: .NET , LINQ
  • VS2010 RC: Much Faster than Beta 2

    I spent all day yesterday working with VS2010 RC. (MSDN Subscribers could download late on Monday. It becomes public today). First impression:  It is much faster, and more stable than the beta 2 build...
  • Its 2010 and there is still not a good audio manager

    Its 2010 and iTunes is still slow. Windows Media Player does this 5-20 times a day: So there are no good comprehensive media library managers. Its sad but true. I think tomorrow I’ll be going back to using foobar2000 for my audio listening. WMP12 was so so so close for me, but this issue is a [...]
  • double.IsNaN is 100 times slower

    Its not just your programming group that can’t get it right. I work in a semi-disfunctional group on contract for a client who, not matter how hard we try, doesn’t seem to listen to basic software engineering principles. I feel a little better (and a great deal worse after thinking about it) when I see that [...]
  • Euler Problem 14: Learn to Memoize

    This is going to be fun. It’s a bit of LINQ, a bit of academic Computer Science, and a bit of meteorology. Euler Problem 14 concerns a sequence referred to as hailstorm numbers. Hailstorm number...
  • Super-simple Object Mapper

    If you need a full-featured object mapper with minimal set up, I recommend you take a look at AutoMapper on Codeplex.  If you need a quick-and-dirty solution, maybe the following code could help you out. First off, why am I not using AutoMapper?  At my current client, there are strict rules as to the use of open source software.  There's a process in place for requesting the use of a particular open source tool, but with the red-tape of the approval process (reviews, signatures, justification, etc…), it could literally take 3 – 6 months.  It's just not worth it for what I need right now.  So I rolled my own. This mapper is super-simple, not very smart and may have a bug or two in it, but it works for what I need it to do and reduces a lot of hand coding.  USE AT YOUR OWN RISK! It uses two simple rules to map data between two objects: If a property name and type on the source match the name and type of a destination property, the value is copied. If the user has defined a custom mapping action, use that to copy data (but rule #1 is always executed first). Let's dig into the details. First, I set up a generic class that takes in a couple of types – my source and destination types.  I added a clause on the destination type that it must be 'new-able' so that I could provide a utility function that would create a destination object, map it's values from a source and return it to you. public class Mapper<TSource, TDest> where TDest : new () {   } Copying Properties When copying data from a source object to a destination object, we get all public instance properties of the destination and see if they have a matching (same name and same type) property on the source.  If so, we set the value on our destination object: protected virtual void CopyMatchingProperties(TSource source, TDest dest) { foreach (var destProp in typeof (TDest).GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(p => p.CanWrite)) { var sourceProp = typeof (TSource).GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(p => p.Name == destProp.Name && p.PropertyType == destProp.PropertyType). FirstOrDefault(); if ( sourceProp != null ) { destProp.SetValue(dest, sourceProp.GetValue(source, null ), null ); } } } Custom Transformations I want the ability to define my own transformation for special cases.  This is simply a list of Action<TSource, TDest> delegates: protected readonly IList<Action<TSource, TDest>> mappings = new List<Action<TSource, TDest>>();   public virtual void AddMapping(Action<TSource, TDest> mapping) { mappings.Add(mapping); } Again, simple yet functional. Perform Mappings The last thing we need is a couple of methods to execute the actual mapping: public virtual TDest MapObject(TSource source, TDest dest) { CopyMatchingProperties(source, dest); foreach (var action in mappings) { action(source, dest); }   return dest; }   public virtual TDest CreateMappedObject(TSource source) { TDest dest = new TDest(); return MapObject(source, dest); } You'll see that "CreatedMappedObject" was the reason we needed to have the new-able clause on the TDest generic parameter. Usage Now let's put this into action!  Given a simple domain object and view model: public class DomainObject { public string Name { get; set; } public DateTime DOB { get; set; } public int Age { get; set; } public string Address { get; set; } }   public class ViewModel { public string Name { get; set; } public int Age { get; set; } } As you can see, our view model only needs the Name and Age.  Our mapping code looks like this: var mapper = new Mapper<DomainObject, ViewModel>(); var viewModel = mapper.CreateMappedObject(domainObject); if the view model is created somewhere else and pre-populated with other data, we would use the MapObject method instead of creating a new instance of ViewModel: var mapper = new Mapper<DomainObject, ViewModel>(); var viewModel = InitializeViewModel(); viewModel = mapper.MapObject(domainObject, viewModel); Now let's assume we want to add the user's birth year to the view: public class ViewModel { public string Name { get; set; } public int Age { get; set; } public int BirthYear { get; set; } } Yes, we could pass along the entire date of birth, but this way the view model is getting only what it needs and doesn't need to do any additional processing to get the year: var mapper = new Mapper<DomainObject, ViewModel>(); mapper.AddMapping((source,dest) => dest.BirthYear = source.DOB.Year); var viewModel = mapper.CreateMappedObject(domainObject); To encourage re-use and centralize the setup of any custom transformations, I create a subclass of my Mapper class: public class DomainModelToViewModelMapper : Mapper<DomainObject, ViewModel> { public DomainModelToViewModelMapper() { this .AddMapping((s, d) => d.BirthYear...

Before I discuss my 2010 predictions, it’s important to provide a disclaimer using my 2009 predictions.  One of my predictions was spot on. ...

SRT is proud to sponsor and participate in the following events. We hope you will join us.

SRT Solutions
206 S. Fifth Ave., Suite 200
Tuesdays 5:30-6:30

Blau Aud, Ross School of Business
701 Tappan St
Ann Arbor MI
Thursday, March 4

Town Center Dr., Southfield, MI 48075
Tuesday, March 30 1000

Ann Arbor Hands on Museum
220 E. Ann St. Ann Arbor, MI 48104
Saturday, March 22