Leaving Microsoft

Monday, August 22, 2011 5:04 AM

Remember last December when I wrote the post titled New Job about this incredibly awesome opportunity I was really excited about? Here I am less than a year later saying goodbye already. My last day with Microsoft is September 9th.

I truly believe an ADM and the PSfD organization as a whole to be a valuable investment for companies with development staff, but it's just not for me personally. Though it is a highly technical position and I did some code-centric work, I would say it is dominantly managerial and it contains a great deal of support responsibility. I've always claimed that I could never be a manager and I don't think I'm cut out for providing support. Maybe it's my near zero empathy score - don't know. Maybe I've found my level of incompetence! Most importantly though, I really miss just being a developer.

At first I thought about moving around inside the company. I thought I'd look for a development position that would allow me to work remotely since I'm anchored to the area (willingly). After all, Microsoft is an excellent company to work for. Great pay, great benefits, and it's full of extremely smart people who are also fun to be around (for you social types). In the end though, the wife and I decided this would be the perfect time for me to chase dreams. Dreams of working for myself and becoming a Micro ISV.

I'm not entirely sure at this point how I'm going to accomplish this, but I'm going to give it a go. In the beginning I'll be an independent contractor and take jobs as I find them to help financially. Mostly I'm going to be doing a lot of research and investigating a few ideas. Oh, and when I don't have a contract, I'm going to pick up my youngest daughter earlier and hopefully be home when my oldest gets off the bus. Might even make supper for the wife if she can stomach it.

Tags: work

In Memory Repository

Wednesday, July 13, 2011 9:28 AM

I mentioned to a buddy the in memory repository I've used on a few projects. He asked me to share so here it is...

Two things to note. The Entity base class has a single property on it called Id. And remember that the InMemoryRepository isn't transactional so everything done is immediate and submitting changes or rolling back on the unit of work has no effect. You could certainly add this behavior of course, but as-is doesn't bother with it.

public interface IRepository
{
  T Get<T>(int id) where T : Entity;
  T Get<T>(Expression<Func<T, bool>> predicate) where T : Entity;

  IQueryable<T> Find<T>() where T : Entity;
  IQueryable<T> Find<T>(Expression<Func<T, bool>> predicate) where T : Entity;

  T Add<T>(T entity) where T : Entity;
  T Remove<T>(T entity) where T : Entity;
}

public class InMemoryRepository : IRepository
{
  public InMemoryRepository()
  {
  }

  public InMemoryRepository(bool clear)
  {
    if (clear)
      _lists.Clear();
  }

  public T Get<T>(int id) where T : Entity
  {
    return Get<T>(x => x.Id == id);
  }

  public T Get<T>(Expression<Func<T, bool>> predicate) where T : Entity
  {
    return Find<T>().SingleOrDefault(predicate);
  }

  public IQueryable<T> Find<T>() where T : Entity
  {
    return ListFor<T>().AsQueryable();
  }

  public IQueryable<T> Find<T>(Expression<Func<T, bool>> predicate) where T : Entity
  {
    return Find<T>().Where(predicate);
  }

  public T Add<T>(T entity) where T : Entity
  {
    ListFor<T>().Add(entity);
    return entity;
  }

  public T Remove<T>(T entity) where T : Entity
  {
    ListFor<T>().Remove(entity);
    return entity;
  }

  /**********************************************************************/
  /**********************************************************************/

  private static readonly IDictionary<Type, object> _lists = new Dictionary<Type, object>();
  private static readonly object _lockObject = new object();

  private static IList<T> ListFor<T>()
  {
    var type = typeof(T);

    if (!_lists.ContainsKey(type))
    {
      lock (_lockObject)
      {
        if (!_lists.ContainsKey(type))
        {
          Type listType = typeof(List<>).MakeGenericType(type);
          _lists[type] = Activator.CreateInstance(listType);
        }
      }
    }

    return (IList<T>)_lists[type];
  }
}
Tags: .net

Equality Members

Thursday, June 16, 2011 11:48 AM

I was watching a presentation today and noticed an implementation of GetHashCode() that was... less than perfect :)

For those without the luxury of Resharper, I thought I'd create a few examples of implementing the equality members. For a refresher on defining equality, see this MSDN article. Note that, while technically optional, it is recommended to overload the == and != operators too.

public class IntPrimaryKey : IEquatable<IntPrimaryKey>
{
    public int PrimaryKey { get; set; }

    public bool Equals(IntPrimaryKey other)
    {
        if (ReferenceEquals(null, other)) return false;
        if (ReferenceEquals(this, other)) return true;
        return PrimaryKey == other.PrimaryKey;
    }

    public override bool Equals(object obj)
    {
        return Equals(obj as IntPrimaryKey);
    }

    public override int GetHashCode()
    {
        return PrimaryKey;
    }
}

public class StringPrimaryKey : IEquatable<StringPrimaryKey>
{
    public string PrimaryKey { get; set; }

    public bool Equals(StringPrimaryKey other)
    {
        if (ReferenceEquals(null, other)) return false;
        if (ReferenceEquals(this, other)) return true;
        return Equals(PrimaryKey, other.PrimaryKey);
    }

    public override bool Equals(object obj)
    {
        return Equals(obj as StringPrimaryKey);
    }

    public override int GetHashCode()
    {
        return PrimaryKey == null ? 0 : PrimaryKey.GetHashCode();
    }
}

public class MultiNumberPrimaryKey : IEquatable<MultiNumberPrimaryKey>
{
    public int PrimaryKey1 { get; set; }
    public int PrimaryKey2 { get; set; }

    public bool Equals(MultiNumberPrimaryKey other)
    {
        if (ReferenceEquals(null, other)) return false;
        if (ReferenceEquals(this, other)) return true;
        return PrimaryKey1 == other.PrimaryKey1 && PrimaryKey2 == other.PrimaryKey2;
    }

    public override bool Equals(object obj)
    {
        return Equals(obj as MultiNumberPrimaryKey);
    }

    public override int GetHashCode()
    {
        unchecked
        {
            return (PrimaryKey1 * 397) ^ PrimaryKey2;
        }
    }
}

public class MultiStringPrimaryKey : IEquatable<MultiStringPrimaryKey>
{
    public string PrimaryKey1 { get; set; }
    public string PrimaryKey2 { get; set; }

    public bool Equals(MultiStringPrimaryKey other)
    {
        if (ReferenceEquals(null, other)) return false;
        if (ReferenceEquals(this, other)) return true;
        return Equals(PrimaryKey1, other.PrimaryKey1) && Equals(PrimaryKey2, other.PrimaryKey2);
    }

    public override bool Equals(object obj)
    {
        return Equals(obj as MultiStringPrimaryKey);
    }

    public override int GetHashCode()
    {
        unchecked
        {
            return ((PrimaryKey1 == null ? 0 : PrimaryKey1.GetHashCode()) * 397) ^ (PrimaryKey2 == null ? 0 : PrimaryKey2.GetHashCode());
        }
    }
}

public class MultiMixedPrimaryKey : IEquatable<MultiMixedPrimaryKey>
{
    public int PrimaryKey1 { get; set; }
    public string PrimaryKey2 { get; set; }

    public bool Equals(MultiMixedPrimaryKey other)
    {
        if (ReferenceEquals(null, other)) return false;
        if (ReferenceEquals(this, other)) return true;
        return PrimaryKey1 == other.PrimaryKey1 && Equals(PrimaryKey2, other.PrimaryKey2);
    }

    public override bool Equals(object obj)
    {
        return Equals(obj as MultiMixedPrimaryKey);
    }

    public override int GetHashCode()
    {
        unchecked
        {
            return (PrimaryKey1 * 397) ^ (PrimaryKey2 == null ? 0 : PrimaryKey2.GetHashCode());
        }
    }
}

public class MultiPrimaryKey : IEquatable<MultiPrimaryKey>
{
    public int PrimaryKey1 { get; set; }
    public int PrimaryKey2 { get; set; }
    public int PrimaryKey3 { get; set; }
    public int PrimaryKey4 { get; set; }

    public bool Equals(MultiPrimaryKey other)
    {
        if (ReferenceEquals(null, other)) return false;
        if (ReferenceEquals(this, other)) return true;
        return PrimaryKey1 == other.PrimaryKey1 && PrimaryKey2 == other.PrimaryKey2 && PrimaryKey3 == other.PrimaryKey3 && PrimaryKey4 == other.PrimaryKey4;
    }

    public override bool Equals(object obj)
    {
        return Equals(obj as MultiPrimaryKey);
    }

    public override int GetHashCode()
    {
        unchecked
        {
            int result = PrimaryKey1;
            result = (result * 397) ^ PrimaryKey2;
            result = (result * 397) ^ PrimaryKey3;
            result = (result * 397) ^ PrimaryKey4;
            return result;
        }
    }
}

public class MultiPrimaryKey2 : IEquatable<MultiPrimaryKey2>
{
    public string PrimaryKey1 { get; set; }
    public string PrimaryKey2 { get; set; }
    public string PrimaryKey3 { get; set; }
    public string PrimaryKey4 { get; set; }

    public bool Equals(MultiPrimaryKey2 other)
    {
        if (ReferenceEquals(null, other)) return false;
        if (ReferenceEquals(this, other)) return true;
        return Equals(PrimaryKey1, other.PrimaryKey1) && Equals(PrimaryKey2, other.PrimaryKey2) && Equals(PrimaryKey3, other.PrimaryKey3) && Equals(PrimaryKey4, other.PrimaryKey4);
    }

    public override bool Equals(object obj)
    {
        return Equals(obj as MultiPrimaryKey2);
    }

    public override int GetHashCode()
    {
        unchecked
        {
            int result = PrimaryKey1 == null ? 0 : PrimaryKey1.GetHashCode();
            result = (result * 397) ^ (PrimaryKey2 == null ? 0 : PrimaryKey2.GetHashCode());
            result = (result * 397) ^ (PrimaryKey3 == null ? 0 : PrimaryKey3.GetHashCode());
            result = (result * 397) ^ (PrimaryKey4 == null ? 0 : PrimaryKey4.GetHashCode());
            return result;
        }
    }
}
Tags: .net, bestpractices

Certified

Wednesday, February 23, 2011 7:35 PM

I spent last week at TechReady12 and I have to say, it was AWESOME!! I met a lot of new people and attended some really great sessions. I could be mistaken, but I got the feeling that we as a company are somewhat interested in this whole cloud thing.

One of the things being offered there was free testing for Microsoft Certifications. Being the incredibly lazy developer that I am, I thought it would be smart take a few tests without studying just to see what happens. I figured if I study and pass a test that I would have passed anyway, all time spent studying was wasted effort on my part. Unacceptable..

Well, I took four tests and passed all four! That's right, after all these years I'm actually certified in something. These are the tests I passed:

The first three MCTS certificates are prerequisites to the MCPD. Having passed all four makes me:

Now the only decision is whether or not to go ahead and push on to the full MCITP. That will require my passing just three more certs:

Passing any one of these however, will definitely require some studying on my part.

It's easy to play down the accomplishment so far since I didn't study. But I must say, I'm glad I did it. Feels great :)

Tags:

New Job

Sunday, December 5, 2010 8:35 PM

Cut to the Chase

I'm leaving Tyson Foods for a position with Microsoft.

Looking Back

This coming March would have been my 10 year mark with Tyson (with the exception of a one year stint). Even though I'm crazy excited about the new position and the fact that it's Microsoft, this was an incredibly hard decision. Tyson has treated me great and I honestly feel I had a long and bright future with them. In my mind, I was giving up a lot and I was leaving behind some really, really good relationships. In fact, this wasn't a change I was actively looking for. An opportunity was presented to me and because it was Microsoft, I couldn't resist at least giving it a look. The next thing I knew (at least that's the way it seemed), they made an offer. This might sound nuts, but I almost turned it down! In the end though, I recognized this as an awesome opportunity and realized I'd be crazy to pass it up. Tyson, thank you for an excellent start to my career, thank you for all the great friendships, and thank you for being a great employer.

Looking Forward

No, I'm not moving to Redmond. My new position is an Application Development Manager with Microsoft Premier Support Services in the Bentonville, AR area. I'll let your imagination fly as to what company in northwest Arkansas would pay for that level of support ;). This is the formal job description:

The Premier Support for Developer offering is part of Microsoft Premier Support Services. The purpose of the Application Development Manager (ADM) role is to provide our customers with a technically competent advocate with access to all of the resources at Microsoft, to advise and consult on the use of Microsoft technology in their particular product or application. Tasks performed in this role include helping with technology assessments, workshops, prototyping, conducting application design reviews, performance benchmarks, code reviews, porting/migration assistance, configuration management and general development consulting. Key to the success of this role is the ability to develop and maintain strong trust/working relationships with assigned accounts and constantly expanding the working knowledge of current and pre-release Microsoft systems, products and platforms.

Responsibilities:
The ADM is responsible for understanding the customer's environment, its technical requirements and fit to Microsoft technologies. The ADM serves as the customer's persistent Microsoft point of contact throughout the customer's product development lifecycle, which is a role that is heavily reliant on the ADM possessing excellent customer service skills. The ADM is required to assist the team with quick and efficient resolution of customer's reactive support needs. The ADM will deliver prescriptive consulting guidance in the form of workshops, reviews, prototypes, white papers, and conclusive test results while setting realistic expectations regarding the capabilities and delivery timeframes of Microsoft technologies. It is vital that the ADM works continuously on keeping up-to-date on new Microsoft technologies relevant to the customer's particular needs, while developing relationships with key Microsoft product group resources. The ADM is expected to maintain a collaborative role with customers. The ADM is expected to provide consulting assistance to peers as project workloads allows. The ADM also maintains relationships with Microsoft product managers, providing feedback on product requirements and driving product feature/functionality requests on behalf of Premier customers.

My description: pure awesome! My wife has told me many times that she thinks I have organizational ADD. I get bored insanely fast on projects. Some of my favorite times at Tyson were the times when I got loaned to other teams. Other favorites include devloop and when other team members came to me for help or advice. With this in mind, the new role really does seem like a perfect fit for me.

Needless to say, I'm excited. Wish me luck and stay in touch. You'll always be able to find me at the monthly DNUG meetings.

Tags: work