In every application I’ve every written, I’ve had to deal with state values in some way. At the simplest level, you’ll usually need to know the answer to three questions.

  1. Is there currently an authenticated user?
  2. Who is the current user?
  3. What is the current user allowed to do?

Just about every web application needs to solve these three problems. In fact, this very question was posed by a comment from my previous post. In the commenter’s example, he has a separation of layers that will not allow him to access things like HTTP context or session from his data tier library. (There’s no reference to System.Web from the data tier.)

You know what I’m thinking? This sounds like an interface!

public interface IUserState
{
  bool IsAuthenticated { get; }
  string UserName { get; }
  string[] Roles { get; }
}

This is a bit of a trick in a web environment, because the web is naturally stateless. You can’t use statics the same as you would with a desktop application. You must use a factory, similar to how HttpContext.Current is resolved.

I should point out that the concept of a user state is even lower than your data tier.

public class UserState
{
  private static IUserStateFactory factory;

  public static IUserState Current
  {
    get { return factory.UserState; }
  }

  public static void SetFactory(IUserStateFactory userStateFactory)
  {
    factory = userStateFactory;
  }
}

This part is important: we cannot store the user state instance in a static field. This is one of the biggest sources of problems that I find when working with ASP.NET application. (I’ve seen this all too often in both WebForms and MVC. Remember, the underlying ASP.NET technology is the same.) The static field life cycle is stored within the AppDomain. In an ASP.NET project, this AppDomain is not guaranteed to go to the same user every time. When you have multiple users on a web page. However, we can easily save the factory in a field, since the role of a factory is to create the objects.

Now, we need some implementations that will work with an HTTP session.

public class HttpSessionUserState : IUserState
{
  private readonly HttpSessionState session;

  public HttpSessionUserState(HttpSessionState session)
  {
    this.session = session;
  }

  public bool IsAuthenticated
  {
    get { return UserName != null; }
  }

  public string UserName
  {
    get
    {
      object userName = session["UserName"];
      return (userName != null) ? (string)userName : null;
    }
  }

  public string[] Roles
  {
    get
    {
      object roles = session["Roles"];
      return (roles != null) ? (string[])roles : new string[] { };
    }
  }
}

Yes, I prefer to return an empty array of roles, rather than null, in this case. The way .NET deals with nulls is a constant source of frustration, and I hate seeing NullReferenceException’s sprinkled through the error logs.

We also need an implementation of the factory.

public class HttpSessionUserStateFactory : IUserStateFactory
{
  public IUserState UserState
  {
    get
    {
      var session = HttpContext.Current.Session;
      return new HttpSessionUserState(session);                
    }
  }
}

To round out this example we need to register the factory with the static class. This should be done as part of your application startup. In a web app, that means you should put this in your Global.asax file. Create a method like this, and add a call to this method to your Application_Start.

private void RegisterUserStateFactory()
{
  var userStateFactory = new HttpSessionUserStateFactory();
  UserState.SetFactory(userStateFactory);
}

This is a little lengthy. We’re looking at 5 total classes, but all of the classes are quite small. The first three classes are in a base layer. The specific implementations are in your are part of your startup layer. This works because we are depending on an interface, not a specific implementation. Unit testing is quite easy as well. We can create InMemoryUserState and InMemoryUserStateFactories quite easily, or we can just mock out their implementations.

Back to my previous post

Updating modified entries now needs to look something like this.

private void UpdateModifiedEntries()
{
  var modifiedEntries = ChangeTrackerEntries.Where(e => e.State == EntityState.Modified && e.Entity is IAuditable).Select(e => e.Entity);
  foreach (var modifiedEntry in modifiedEntries)
  {
    modifiedEntry.UpdatedAt = DateTime.UtcNow;
    modifiedEntry.UpdatedBy = UserState.Current.UserName; // used to be HttpContext.Current.UserName
  }
}

Happy to help!

Another pretty common problem – we have a lot of tables that have the same 4 columns to track simple audit information. I’m sure you’ve all seend something like this before.

  CreatedAt    DATETIME NULL,
  CreatedBy    VARCHAR(256) NULL,
  UpdatedAt    DATETIME NULL,
  UpdatedBy    VARCHAR(256) NULL

When inserting or updating records, we really don’t want to mess around with updating all of this stuff all of the time, especially if you have a lot of models in your application. It’s just a pain, and it violates DRY. So let’s fix that.

The first thing we need is an interface. We’ll implement this interface on all of our models that have this audit tracking information.

public interface IAuditable
{
  DateTime? CreatedAt { get; set; }
  string CreatedBy { get; set; }
  DateTime? UpdatedAt { get; set; }
  string UpdatedBy { get; set; }
}

Now we need to look to our DbContext for further insights. (I’m using the DbContext code generator, available as a Visual Studio Extension.) We see that our entity context extends the DbContext, and it’s created as a partial class by default. Let’s take advantage of this and override the SaveChanges method.

partial class MyContext
{
  public override int SaveChanges()
  {
    UpdateAuditInformation();
    return base.SaveChanges();
  }

  private IEnumerable ChangeTrackerEntries
  {
    get { return this.ChangeTracker.Entries(); }
  }

  private void UpdateAuditInformation()
  {
    UpdatedAddedEntries();
    UpdatedModifiedEntries();
  }

  private void UpdateAddedEntries()
  {
    var addedEntries = ChangeTrackerEntries.Where(e => e.State == EntityState.Added && e.Entity is IAuditable).Select(e => e.Entity);
    foreach (var addedEntry in modifiedEntries)    
    {
      addedEntry.CreatedAt = DateTime.UtcNow;
      addedEntry.CreatedBy = HttpSession.Current.UserName;
      addedEntry.UpdatedAt = addedEntry.CreatedAt;
      addedEntry.UpdatedBy = addedEntry.CreatedBy;
    }
  } 

  private void UpdateModifiedEntries()
  {
    var modifiedEntries = ChangeTrackerEntries.Where(e => e.State == EntityState.Modified && e.Entity is IAuditable).Select(e => e.Entity);
    foreach (var modifiedEntry in modifiedEntries)
    {
      modifiedEntry.UpdatedAt = DateTime.UtcNow;
      modifiedEntry.UpdatedBy = HttpSession.Current.UserName;
    }
  }
}

The HttpSession.Current is just a strongly typed wrapper for an HTTP session, specific to this application. There’s nothing special, so feel free to use any method available to get the current application user. For example, if you’re using FormsAuthentication or WindowsAuthentication, you can simply call HttpContext.Current.User.

Hope you like it!

I have written before that I have to interview incoming developer candidates. It is not my favorite part of my job. Sure, I love geeking out with other developers, but that happens so rarely. It’s embarrassing, really. I didn’t make this up on my own. There’s plenty of other people out there who do this.

Why A Code Sample?

Because just having one tells us a lot about you. No, we do not expect you to go home and spend 6 – 8 hours programming. But do you do anything at all outside of work? Do you ever contribute to open source projects? Did you ever write a little program to teach yourself something new? Me? I’m a geek. (We’ve clearly established this.) I maintain my own public & shared NuGet repositories, and my code is freely available on GitHub.

But that’s not for everyone. That’s OK; do what you do. But do something! This is partly what Stephen Covey would call Sharpening the Saw. What do you do to keep your skills fresh and up-to-date? How do you learn? What are you working on? If you want to succeed in today’s development world, you need to be tinkering. With something. Anything. And while you’re at it, check your code into a public code repository. I doesn’t even cost anything to share your ideas.

What Are The Rules?

They’re fairly straightforward. Send us something you’ve done that demonstrates your ability as a software developer. It can be big or little, just make sure that you have permission to send it. It should not be proprietary software that belongs to a previous employer. It’s probably not

What Are We Looking For In A Code Sample?

Honestly, not much. It can be anything. If it’s a language I can read, I’ll take it. Sure, I’d prefer it to be in C#.NET, since that’s what we’re hiring you to do, but I’ll accept Python, Ruby, VB, JavaScript, etc. For what it’s worth, I’d even accept MatLab.

Isn’t This Supposed To Be A Horror Story?

Yes. Yes, it is.

Some people have outstanding resumes and absolutely no code sample at all. It happens, and we might still interview you. In fact, if you can talk the talk well enough, you might not even need a code sample. That, in fact, is a better option than sending us an absolutely terrible code sample. I got to see one today: 1 class, 4 methods (Create, Fetch, Update, List All), 19 pages when printed. No concept of DRY. Validating each property in sequence with a lovely series of if statements. And, of course, they’re all copy/paste duplicated for create and update options. Just absolutely horrible, monstrous code.

Or, this is the email I sent my boss this morning.

When you compare nothing to nothing, there’s not much there to work with. This, however, is the difference between going on a blind date and knowing up front that the other person is ugly.

Don’t get me wrong. I will freely admit to having had written programs that look like that. You know, back before I knew what I was doing. Before I had a clue about LoB software development.

Despite my complaints, I must interview the candidate anyway, and this does not make me happy.

The more code I write, the more I find myself using delegates. Take this part of our Curiosity.Common.Mvc library, just added today. Behold, the power of delayed execution.

return new FormHandlerResult<Logon>(form, () => RedirectToAction("Index", "Home"), () => View(form))
{
SuccessNotification = () => "Welcome, " + Session["display_name"]
}

I have a dynamic success notification in this case. The form handler will update the session with the display name, but it’s not set yet. If I were to just use a string for success notification, I couldn’t set the string at a later time. In this case, using a Func<string> solves all of my problems.

It’s been a long, long time since I ran a half-marathon. It’s November, and this is my first one this year. But I’ve also learned that I’m capable of much faster times than what I’ve submitted in the past. It’s really just a matter of making your legs go faster.

Mile 1 - 9:18. Seems like a fast start. That’s OK. I know I’ll slow down, and I know I have problems pacing myself. Fast is OK.
Mile 2 & 3 – 17:40. I never did see the 2nd mile marker. Meaghan did, so there must have been one. Whatever. Still, a fast start. That’s like, 2 miles where I averaged 8:50/mile.
Mile 4 - 8:32. This is where I passed Meaghan. She even yelled out to me, “You’re going faster than 9:00/mile.” I knew that; my watch was working. But, damn, I felt really, really good this morning.
Mile 5 – 9:23.
Mile 6 – 8:46. Obviously, consistency is not my strong suit here. Still, 6 miles at 53:41 would have led to a 10k PR. In fact, let me show you them. My 10k time was 55:43 – that’s 9:00/mile flat! My best 10k was just a few weeks ago at a 9:17/mile pace. So now I’m thinking that my next 10k needs to be in sub-9/mile.
Mile 7 – 9:00. At this point, my mind starts thinking that I can finish in under 2:00.
Mile 8 – 9:30. Um, maybe not.
Mile 9 – 9:20. Or maybe.
Mile 10 – 9:18. OK, this is crazy, and my mind is really flying around now. That’s 3 really consistent miles. We’ve already established that consistency is not my strong suit. I look at my watch. 1:30:51. I needed to run a 5k in 29 minutes. In theory I could do that – better than that even – but I had just ran the greatest 10 miles of my life. My legs were already aching. And that seed is planted: sub-2:00 isn’t going to happen. And once that seed gets in your head, that’s it. You’ve lost the brain game.
Mile 11 – 10:21. This is not how you run a 5k in 29:00.
Mile 12 – 10:02. Still going the wrong way.
Mile 13 – 10:25. Well, shit.
Mile 13.1 – 0:59. Total time was 2:02:40 by my watch, 2:02:39 by the timing chip, and 2:04:30 by the clock. The watch/chip time comes out to 9:22 per mile, which is good enough for preferred seeding for Indianapolis Mini Marathon.

Don’t get me wrong. Getting a PR and beating my goal time of 2:05 by better than 2 minutes is an outstanding result. But I also watched a sub-2 slip through my toes via my brain. I lost that in my head before I ever lost it in my legs.

I can definitely tell that hanging out with athletes is having an effect on my energy level. It’s Sunday, and I’ve already registered for a full marathon, the Illinois Marathon, on April 28. I’ve also registered for a half Ironman, Muncie, on July 7. I absolutely must figure out the head game thing in the next 6 months, or I’ll never finish either of those events.

I don’t play a lot of video games. That’s not terribly upsetting, since I was never a real hard-core gamer anyway. I like video games, but I’m not really that good at them. I’m more of the turn-on-God-mode-to-see-what-the-end-is-like type of gamer. No, that’s not for everyone, but it works for me.

So even though I don’t play them, I do like to read about the games. One of the feeds in my reader is Penny Arcade. Well, imagine my surprise when I read this – an article about Child’s Play. Between 2003 and 2010, Child’s Play has managed to raise $8.9 million. That’s an outstanding contribution from the gaming world.

But it’s something that makes me happy/sad. These kids are going through terrible illnesses that no one should have to endure. Let’s say this: they’re not buying consoles and games for kids in the Dr.’s office with runny noses. This is big-time illness.

I encourage you to check out Child’s Play. Give them a few bucks. Stand in awe of the healing power of Mario Kart.