Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Providing custom database functionality to custom asp.net membership provider

I am creating custom membership provider for my asp.net application. I have also created a separate class "DBConnect" that provides database functionality such as Executing SQL statement, Executing SPs, Executing SPs or Query and returning SqlDataReader and so on...

I have created instance of DBConnect class within Session_Start of Global.asax and stored to a session. Later using a static class I am providing the database functionality throughout the application using the same single session. In short I am providing a single point for all database operations from any asp.net page.

I know that i can write my own code to connect/disconnect database and execute SPs within from the methods i need to override. Please look at the code below -

public class SGI_MembershipProvider : MembershipProvider
{

......

    public override bool ChangePassword(string username, string oldPassword, string newPassword)
    {
        if (!ValidateUser(username, oldPassword))
            return false;

        ValidatePasswordEventArgs args = new ValidatePasswordEventArgs(username, newPassword, true);

        OnValidatingPassword(args);

        if (args.Cancel)
        {
            if (args.FailureInformation != null)
            {
                throw args.FailureInformation;
            }
            else
            {
                throw new Exception("Change password canceled due to new password    validation failure.");
            }
        }

.....        

//Database connectivity and code execution to change password.

}

....

}

MY PROBLEM - Now what i need is to execute the database part within all these overriden methods from the same database point as described on the top. That is i have to pass the instance of DBConnect existing in the session to this class, so that i can access the methods.

Could anyone provide solution on this. There might be some better techniques i am not aware of that. The approach i am using might be wrong. Your suggessions are always welcome.

Thanks for sharing your valuable time.

like image 886
IrfanRaza Avatar asked Apr 14 '10 09:04

IrfanRaza


2 Answers

Understanding the lifecycle of the membership provider would help clear this up.

An instance of the membership provider is spun up when the application is started and remains active for the lifetime of the application AppDomain, which in practice equates to the application lifecycle. e.g. If for some reason the AppDomain cycles, the application is disposed and a new instance is spun up. A new instance of the registered membership provider is spun up on first use.

You need to either instantiate an instance of you data access class within your membership provider implementation or access static methods from within your provider. I prefer to use an instance.

Separating the membership provider from it's data access by creating singletons or stashing it in application is a hack in my opinion and will lead to nothing but pain, sorrow, lost sleep and credibility amongst your peers.

Cheers and good luck.

like image 146
Sky Sanders Avatar answered Sep 29 '22 06:09

Sky Sanders


Dont keep a seperate instance of the DBConnect class in session, you will end up creating a class for each user! This will seriously affect scalability.

You can do one of the following :

  • Place the class in Application state
  • Use the singleton pattern
  • Make the class and all the methods in the class static.

My recommendation is to go for number 3. You dont usually need to create an instance of a class that does database crud operations eg

public static class DBConnect
{
  public static ChangePassword(string userId, string password)
  {
    //Implementation here
  }
}

Then you can simply call this code in your provider without creating an instance:

DBConnect.ChangePassword(x,y);
like image 24
James Westgate Avatar answered Sep 29 '22 07:09

James Westgate