March 25, 2010

Inserting a MembershipProvider into the MembershipProviderCollection programmatically

The Membership.Providers MembershipProviderCollection is supposed to be maintained through the web.config. However there are times when you don't wish to use the web.config - perhaps for unit testing, or even just for prototyping something where you want to test a provider in isolation.

If you attempt to inject a MembershipProvider into the collection programmatically, you will have come across the exception 'Collection is read-only'. This is to prevent you from injecting membership providers willy nilly and not following the workflow that the .NET team would prefer you use.

Disclaimer: The code I'm using below is a hack to allow you to bypass the proper channels of adding your provider to the collection and should be used carefully. This code should not be used in a production system. Just because you can do something, doesn't always mean you should.

Okay, now that you've read and understood the disclaimer, you still want to know how to inject your provider into the collection for whatever reason you have. Here is how:

The membership provider collection has an internal field that sets it as read-only. This is set to coerce [and by coerce I mean force] the programmer to use the web.config to add your provider. All we need to do to inject our provider programmatically is set this to read-write. The field is on the ProviderBase base class which means that we can't get at it directly from the MembershipProviderCollection type, we have to traverse up to the base class to get at it; don't worry, it's not complicated.

We're going to use reflection [so don't forget to add the reference to System.Reflection] to grab the MembershipProviderCollection type, and traverse up to the base type to override the private field _ReadOnly and set it to false. Normally this field is set to true, preventing you from writing to the collection.

public static void Main()
{
    //Instantiate my custom provider that 
    //inherits MembershipProvider and set 
    //up a reference to the memberhip 
    //providers collection.
    MembershipProvider mp = 
      new MyProvider();

    MembershipProviderCollection mpc = 
      Membership.Providers;

    //Grab the base type from our collection by 
    //grabbing the type and then grabbing the 
    //type's base type like so:
    Type t = mpc.GetType();
    Type tbt = t.BaseType;

    //Okay, now we've got our base type we can 
    //grab the read only field.
    BindingFlags bindingFlags =
      BindingFlags.Instance | 
      BindingFlags.NonPublic;

    FieldInfo fi = 
      tbt.GetField("_ReadOnly", bindingFlags);

    //Having grabbed a reference to the field, we 
    //can override its value
    fi.SetValue(mpc, false);

    //Now our MembershipProviderCollection is no 
    //longer read-only
    mpc.Add(mp);
}

I guess you could easily create a method to do the injection. I've condensed the code in the following method but it doesn't function any differently than the code above.

public static void InjectProvider(MembershipProvider providerToInject)
{
    MembershipProviderCollection mpc = 
      Membership.Providers;

    mpc.GetType().BaseType.GetField("_ReadOnly", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(mpc, false);

    mpc.Add(mp);
}

public static void Main()
{
    MembershipProvider mp = new MyProvider();
    InjectProvider(mp);

    //If you check your Membership.Providers 
    //in your watch window at this point you 
    //will see that your provider exists in 
    //the collection.

}

So there you have it, you can now programmatically inject your provider into the provider collection. Remember though, Microsoft set this as read-only for a reason. They want you to use the proper channel for adding your provider to the collection, use this only under carefully considered circumstances.

March 8, 2010

How are your development gifts viewed by your company?

This morning @JohnMacIntyre wrote a blog post entitled Timing your exit by the reception of your gifts. While I agree with his point, I thought it might be valuable to provide my perspective on why those gifts may or may not be appreciated by their intended recipient in at least one market.

When a company sees development as a profit centre, then the little gifts are appreciated. There is added value in the product and the savings/revenues generated by the product are immediately reflected upon. This view is frequently seen by companies who are having a good time financially and are seeking to extend the benefit of their good fortune or by companies where development is the core of their business model - i.e. sale of software in some form.

However most companies writing software aren't in the market of selling that software, they're writing it for their own use internally. When a company like this falls on hard times, management frequently reverts to considering development as a cost centre. As pressure mounts and politics set in, managers have to fight harder for the recognition they deserve and in other cases to save face and avoid retribution. They start to point fingers to divert attention away from themselves when they’re asked to account for their shortcomings.

At this point, it doesn’t matter how many value added extras are included in your software if all of the core objectives aren’t completely in order. Those trying to divert the spotlight from themselves will divert it on you, just to get it off themselves.

I digress, my point was this: The minute you start to see development as a cost centre, you cease to consider the value added benefits and immediately view them as a time sink.

Consequently I think the level of appreciation of these gifts boils down to one question: Is the development department looked at as a profit centre or a cost centre within the company?

The answer to this should drive your approach to your workload and hence the company’s perception of your benefit to them.

If it’s looked upon as a profit centre, and you do nothing beyond meeting the core objectives, you’ll be seen as someone who does no more or less than asked – to your benefit or detriment, whichever you decide.

If it’s looked upon as a cost centre and you are always going above and beyond to provide extras that aren’t necessary, then you’ll be looked at as a time waster who can’t focus on the goal.

March 3, 2010

Of a personal nature... [a.k.a. just how bad can one morning with a wife and two kids get?]

I'm not having a great day, it's gotta be said... and 140 characters just wasn't going to cut it this morning. I thought everyone could do with a laugh at my expense because to be honest, if this had happened to anyone else, I'd be laughing at them.

I was awoken by Aimee [my lovely, but sick wife] at 4am to go fetch her "clear pop that has sugar in it and a glass of ice" because she's spent the last 2 hours losing her insides from every possible exit and doesn't have a snowball's chance in hell of getting down two flights of stairs to the basement without falling and breaking her neck. So I drag my ass out of the nice warm bed and down to a freezing cold basement to find the only thing we've got is Tonic Water... which she won't drink. Everything else we have is diet. Fabulous... well, Tonic Water will have to do.

The ice is frozen solid except for the snow in the bottom of the bag; I can't find an ice pick, the meat tenderizer is having no effect and I'm already shivering. I finally manage to break off a chunk that fits in the glass and take it and the Tonic Water up to her.

I fall asleep for what seems like 3 minutes and somehow it's already 6:45am. Charlotte [our 5 week old] has a poopy diaper which Aimee can't deal with without losing her cookies [those at least that she has left to lose], and Aimee's woken Olivia [our 18 month old] up to put her in the bath to get her ready for daycare... and she's already called her Mom to get her to come and help with Charlotte because she doesn't want to get her sick too. Her mum's already on her way over. Crap! I'm totally not ready to get out of bed yet - but because Olivia's in the bath and Aimee's mother's on her way over, I have no choice. Double crap!

I go to change Charlotte to find she doesn't have a poopy diaper at all, I change it anyway, whatever. I go back to the bathroom and turn on the shower to warm it up, I turn back around to find that Olivia's pooped in the bath. Great timing Olivia, perfect. We have to leave in 15 minutes and now not only am I not ready, but I have to bath you in the sink, clean and disinfect the tub and everything that was in it during the poo fiasco of 2010, have a shower, get dressed, get milk and a snack for the car ride, make sure I've got all my stuff for work, put out the recycling and get you strapped into your car seat. It's not looking promising...

I drag her out of the bath and wash her off in the sink and get her dressed and take her downstairs and go back upstairs to empty and disinfect the bath and take a shower. I get done in the shower and go down to grab Olivia to leave the house.

I'm a bit phlegmy because I'm sick and coughing too, which caused me to spend an extra 10 minutes in the bathroom praying to the porcelain gods. I get done with that and go to put Olivia in the car to find that she's got snot covering almost her entire face and is threatening to wipe it all down my work clothes. Gross.

I get her cleaned up and get her in the car to take her to day care and get in to find that I've got no gas left.