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.