RSS

Question: When is a non-static class static?

24 Feb

Answer: When it’s a Provider.

OK, quite an obtuse question there so let me explain…

In our ASP.NET MVC application we have a custom Membership Provider and a custom Role Provider. Here’s a (vastly simplified) example of the membership provider…

public class CustomMembershipProvider : MembershipProvider
{
  private SqlConnection _connection;
  private string _userName;
  private string _password;

  public CustomMembershipProvider()
  {
  }

  public override bool ValidateUser(string username, string password)
  {
    _userName = username;
    _password = password;

    bool success = false;

    try
    {
      // Sets the _cn member...
      OpenConnection();

      success = ValidateUser();
    }
    finally
    {
      CloseConnection();
    }

    return success;
  }
}

So, pretty straight forward. Nothing wrong with that, is there?

Well, actually, yes. The problem is that you may write this class with the expectation that it will be treated as a  POIO (Plain Old Instance Object) but ASP.NET has other ideas. One, and only one, of these objects is instantiated (during the first request to you site). The big issue here is that we now have private fields on a singleton class – not good.

We ran into problems with SqlDataReaders because the runtime complained about multiple readers on the same connection. We could have implemented MARS, but that still didn’t deal with the underlying problem. Worse still is the possibility of an unauthorised user actually being authorised! You only need user1’s time-slice to end and user2’s to begin midway through that ValidateUser method and you’ve got serious problems.

This is a summarised suggestion of how we solved this problem…

public class CustomMembershipProvider : MembershipProvider
{
  public CustomMembershipProvider()
  {
  }
  public override bool ValidateUser(string username, string password)
  {
    bool success = false;

    using (var cn = OpenConnection())
    {
      var validater = new UserValidater(cn, username, password);

      success = validater.IsValid();
    }

    return success;
  }

  private class UserValidater
  {
    private readonly SqlConnection _connection;
    private readonly string _userName;
    private readonly string _password;

    public UserValidater(SqlConnection cn, string userName, string password)
    {
      _connection = connection;
      _userName = username;
      _password = password;
    }

    public bool IsValid()
    {
      // Logic removed for brevity...
    }
  }
}
Advertisements
 
Leave a comment

Posted by on February 24, 2010 in ASP.Net MVC

 

Tags:

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: