March 2010 - Posts

Equality

This is something that I’m surprised isn’t included in the framework out of the box. When using the Distinct Query operator, one of the overloads takes an IEqualityComparer<T> instance. There is friction in creating a separate IEqualityComparer<T> implementation for every object you want to compare and in some cases, Equality means something different depending on context so you don’t necessarily want to implement IEqualiyComparer<T> directly on your T (and/or you aren’t able to do so because it is a class from someone’s library).

Whatever your reason, here is a generic implementation of IEqualityComparer that works similar to my DelegateCommand. You create an instance of it on the spot (or cache an instance) passing in lambdas that represent your equality logic.

public class Equality<T> : IEqualityComparer<T>
{
    private readonly Func<T, int> _hashFunc;
    private readonly Func<T, T, bool> _equalsFunc;

    public Equality(Func<T,int>hashFunc)
    {
        _hashFunc = hashFunc;
        _equalsFunc = (x, y) => x.GetHashCode() == y.GetHashCode();
    }

    public Equality(Func<T,int>hashFunc, Func<T,T,bool>equalsFunc )
    {
        _hashFunc = hashFunc;
        _equalsFunc = equalsFunc;
    }

    public bool Equals(T x, T y)
    {
        //can't compare null
        if (typeof(T).IsClass)
        {
            if (x == null || y == null)
                return false;
        }
        return _equalsFunc(x, y);
    }

    public int GetHashCode(T obj)
    {
        return _hashFunc(obj);
    }
}

The first constructor overload takes just the hash function and specifies that the hashcode is your identifier (great for entities with an Int as their id). The second constructor takes a hash function and an equality function. Using Equality<T> is as simple as:

var manufacturers =
     Catalogs.Select(c => c.Product.ManuFacturer).Distinct(new Equality<ManuFacturer>(i => i.Id));

Hope it’s useful to you!

Posted by Mike Brown | with no comments

Intention Revealing Interfaces or Car.FuelInjectionSystem.FuelInjectionRate.Increase()

I was having a discussion with Josh Smith about my upcoming article in MSDN Magazine on enterprise patterns with RIA Services. It’s basically a deep-dive into the technology that goes beyond the Drag-n-Drop demos you’ve seen so far. Josh’s feedback was generally positive but he had one comment on my section on Domain Models and Intention-Revealing Interfaces. Here’s the section in question

…[quoting Eric Evans’ Domain Driven Design]

If a developer must consider the implementation of a component in order to use it, the value of encapsulation is lost. If someone other than the original developer must infer the purpose of an object or operation based on its implementation, that new developer may infer a purpose that the operation or class fulfills only by chance. If that was not the intent, the code may work for the moment, but the conceptual basis of the design will have been corrupted, and the two developers will be working at cross-purposes.[ (Evans, 2004) pg 246]

To put it simply, by explicitly naming the function for its purpose and encapsulating the logic (along with a few comments to make it clear what’s happening), I have made it easy for the next guy (even if the next guy is me 5 months from now) to determine what is happening before he even goes to the implementation.

Josh’s comment:

So what you’re saying is that I should name my functions according to what they do and write relevant comments?  Seriously? 

I had many similar moments when reading Eric Evan’s book where my response was “well d’uh”. But I got to thinking, how often have I seen code that doesn’t follow this simple rule. To make it patently obvious let’s look at some code that will make a car accelerate:

sCar.FuelInjectionSystem.FuelInjectionRate.Increase()

What’s that, you have an electric car okay:

switch(sCar.Engine.EngineType)
{
    case(EngineType.InternalCombustion)
    {
        sCar.FuelInjectionSystem.FuelInjectionRate.Increase();
    }
    case(EngineType.Electric)
    {
        sCar.Motor.Battery.Amperage.Increase();
    }
}

You’re on your own if you have a Mr. Fusion powered car. I have no idea how they work (although according to FuturePedia the Mr. Fusion doesn’t actually power the car only the Flux Capacitor). But I digress, as the consumer of the car API, I really don’t want to be concerned with fuel injection rates or battery amperages. Please don’t get technical on me and explain that it’s actually wattage that is adjusted on the battery not amperage or whatever snide remark you have regarding the accuracy of my functions. That’s the point of this post because of the car’s design I don’t have to know how it’s done. And neither should the consumer of your car’s API. It should be a simple call:

//look at that!
sCar.Go()

480_S-Car-Go-769045

 

 

That is the point of the intention revealing interface. Instead of making your consumers have intimate knowledge of the innards of your system to make it work, provide them with a simple interface that tells them exactly how to make it do what they want to do.

It may be obvious when you read “explicitly name the function according to its purpose”, but following that advice tends to be less commonplace than it implies.

Posted by Mike Brown | with no comments

Windows Phone 7 the Belle of the Ball

With its noticeable absence from PDC 2008 and 2009, it appeared that Windows Mobile had all but been abandoned. Yes and no. Windows Mobile is no more . Say hello to Windows Phone.

The opening keynote for Mix 2010 was all about Windows Phone 7. If it weren’t patently obvious from the various leaks and pseudo announcements, WP7 uses Silverlight as the primary developer platform. It also supports XNA for game development.

The developer tools for Windows Phone 7 are Free. Included in the tools:

  • Visual Studio 2010 Express
  • Blend 4 for Windows Phone
  • XNA Studio 4 for Windows Phone
  • Windows Phone 7 Device Emulator

All the tools except Blend 4 are included in one handy installer And Christian Schormann shows where you can get the Blend tools here.

The keynote will be available for download tomorrow (in case you missed it). There are a ton of features for Windows Phone 7 that were highlighted in the keynote (I’ll provide a synopsis later). But why are you waiting for me to tell you? Go download it yourself!

2010 MVP Summit Recap (Or How to Slay a Robeast)

No you’re not going to get an inside dish on what to expect at Mix (if you can make it, I HIGHLY suggest you go…unfortunately, an urgent contract popped up for me that prevents me from going…now that I think of it, considering the nature of the contract, I’m sure the client will understand my desire to go to Mix…so maybe I will be able to go). In fact, even if I were crazy enough to break my NDA (I think I can talk about my NDA without breaking it), I wouldn’t be in position to tell you anything. You see, the summit was scheduled at an inopportune time for me this year. Because of its dates:

  1. I was gone on Valentine’s Day
  2. I was still gone on my Wife’s birthday
  3. I wasn’t able to attend any sessions because of a focus group I was attending during the day.

Granted, the Summit alone wasn’t to blame for 1 and 2 because 3 would have had me in Redmond regardless, but missing the sessions was a heartbreaker for me. It’s an opportunity to interact with the product groups and give a lot of feedback and input on the direction they should take for next revs of the products. I can point to two features in Silverlight 4 that I can literally say “That was my idea.” from my participation in last year’s Summit.

DESPITE missing all of the sessions at the Summit, I can still tell you that I would go again in a heartbeat and here is why. I decided that I would fly the red eye on Friday so that I could participate in the side sessions during the day. I ended up…losing interest in the morning keynote and went to the lobby and pulled out the laptop to do some hacking. During a break to “get some fresh air” I met an Exchange MVP who mentioned that he had an idea for some software leveraging Exchange Web Services but that he wasn’t a developer so hasn’t had the time to do anything about it. I listened to his idea and it sounded very interesting. So I asked if he had time and would like to tinker with it.

Two hours later (would have been much quicker if I hadn’t screwed up my Hyper-V configuration…need to remember to blog that experience so that if I bump into it again, I know how to resolve it much more quickly), I’ve got an Exchange server configured for development and the core design of the solution. In addition working on that solution provided some ideas that would be useful in another project.

This is why I love the MVP program. It brings the most knowledgeable people about Microsoft’s products under one umbrella. Learning Exchange on my own would have probably taken me about a week to get it installed. Having an Exchange MVP helped me boil that effort down to about 30 minutes. It probably would have been quite a while before I had enough experience with Exchange before I would have thought of a similar idea independently.

On the other side my new associate who had little recent programming experience gained an “expert” who could help make his vision reality in short order…in fact we already have a simple internal solution in place, the next step is to make it “user friendly”(I’ve heard this is an important feature for commercial products).

What this anecdote demonstrates (and I have a few others from the week)  is a benefit that far outweighs any other that the program offers (although I’ll take those too thank you very much), being able to easily network with recognized community leaders in technology. Think of it like Voltron, individually the lions are powerful, combined they can slay any beast with a single slash of the blazing sword.

Posted by Mike Brown | with no comments