CodeBetter.Com
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @CodeBetter

Mark DiGiovanni

Software Development and Supporting Technologies

August 2003 - Posts

  • Fletcher Dunton is Blogging

    Look out for some great insight from this guy. Fletcher brings many years, decades actually :) in the C++ and VB worlds to the .NET table.

    I have enjoyed working with him and look forward to his regular brain dumps.

    ****UPDATE****
    I thought he was going to blog, I guess not.

  • Self Updating User Controls

    Generally, when the environment permits, I will consolidate all my data access methods into functionally separate classes, for example, admin data access methods will be in the AdminData class.  By standardizing on the method signature, you can easily make self updating user controls.

    Suppose you have several pick lists to maintain in SQL 2000, or any other data source.  Rather than putting several DropDownLists on the page, you can encapsulate that functionality into a user control and reuse it.

    Create a method with the following signature in the data access class:

    c#------------------------------------

    public DataSet UpdateMethodName(string connectionString, DataSet ds, ArrayList additionalParms)

    {

    //This method will update the database.

    }

    VB.NET------------------------------------

    Public Function UpdateRoleList(ByVal connectionString As String, ByVal ds As DataSet, ByVal additionalParms As ArrayList) As DataSet

    'This method will update the database.

    End Function

    The update method should only require a connection string and the dataset to update.  If you need any additional parameters, pass them in as an array list and then handle them as appropriate.

    Create the following public properties in your user control, as well as the public properties (not shown) for the connection string and the dataset that will be updated:

    c#------------------------------------

    public string UpdateClassAndMethodName

    {

    get

    {

    if(ViewState["UpdateMethodName"] != null)

    {

    return (string)ViewState["UpdateMethodName"];

    }

    else

    return "";

    }

    set

    {

    ViewState["UpdateMethodName"] = value;

    }

    }

    /*

    'Use the below ArrayList to specify additional parameters, then handle them as appropriate.

    'Specifying additional properties is optional. Just test for a null ArrayList in the update method, proceed accordingly.

    */

    public ArrayList AdditionalUpdateMethodParameters

    {

    get

    {

    if(ViewState["AdditionalUpdateMethodParameters"] != null)

    {

    return (ArrayList)ViewState["AdditionalUpdateMethodParameters"];

    }

    else

    return (ArrayList)null;

    }

    set

    {

    ViewState["AdditionalUpdateMethodParameters"] = value;

    }

    }

    VB.NET------------------------------------

    Public Property UpdateClassAndMethodName() As String

    Get

    If Not ViewState("UpdateMethodName") = Nothing Then

    Return CStr(ViewState("UpdateMethodName"))

    Else

    Return ""

    End If

    End Get

    Set(ByVal Value As String)

    ViewState("UpdateMethodName") = Value

    End Set

    End Property

    'Use the below ArrayList to specify additional parameters, then handle them as appropriate.

    'Specifying additional properties is optional. Just test for a null ArrayList in the update method, proceed accordingly.

    Public Property AdditionalUpdateMethodParameters() As ArrayList

    Get

    If Not ViewState("AdditionalUpdateMethodParameters") = Nothing Then

    Return CType(ViewState("AdditionalUpdateMethodParameters"), ArrayList)

    Else

    Return CType(Nothing, ArrayList)

    End If

    End Get

    Set(ByVal Value As ArrayList)

    ViewState("UpdateMethodProperties") = Value

    End Set

    End Property

    Create the following method and call it from the “save“ or “update“ button click event:

    c#------------------------------------

    private void DataSaveChanges()

    {

    if(UpdateClassAndMethodName != "")

    {


    string [] fqName = UpdateClassAndMethodName.Split(new Char[] {'.'});

    System.Reflection.Assembly assem;

    object obj;

    string fqText;

    Type updateType;

    MethodInfo updateMethod;

    assem = System.Reflection.Assembly.GetCallingAssembly();

    fqText = assem.FullName.Split(new Char[] {','})[0] + "." + fqName[0];

    updateType = System.Type.GetType(fqText);

    updateMethod = updateType.GetMethod(fqName[1]);

    obj = Activator.CreateInstance(updateType);

    Object [] updateParams = new object[3];

    updateParams[0] = "Connection String Here";

    updateParams[1] = "Data Set Here";

    updateParams[2] = AdditionalUpdateMethodParameters;

    //Make the call

    //You will need to cast this call if the update method's return is not void. for example, the call would be:

    //DataSet returnedSet = (DataSet)updateMethod.Invoke(obj, updateParams);

    updateMethod.Invoke(obj, updateParams);

    }

    }

    VB.NET------------------------------------

    Private Sub DataSaveChanges()

    If Not Me.UpdateClassAndMethodName = "" Then

    Dim fqName() As String = Me.UpdateClassAndMethodName.Split(New Char() {"."})

    Dim obj As Object

    Dim assem As System.Reflection.Assembly

    Dim fqText As String

    Dim updateType As Type

    Dim updateMethod As MethodInfo

    assem = System.Reflection.Assembly.GetCallingAssembly()

    fqText = assem.FullName.Split(New Char() {","})(0) & "." & fqName(0)

    updateType = System.Type.GetType(fqText)

    updateMethod = updateType.GetMethod(fqName(1))

    obj = Activator.CreateInstance(updateType)

    Dim updateParams(2) As Object

    updateParams(0) = SessionManager.GetSessionManager()

    updateParams(1) = cDataSet

    updateParams(2) = AdditionalUpdateMethodParameters

    //Make the call

    //You will need to cast this call if the update method's return is not void. for example, the call would be:

    //returnedSet as DataSet = CType(updateMethod.Invoke(obj, updateParams), DataSet)

    updateMethod.Invoke(obj, updateParams)

    End If

    End Sub

    To set up the page this control will reside on, build the project and drag the control onto the form, next add the following code to the page load, or to your configuration method for the page:

    c#------------------------------------

    MyCustomControl myControl = (MyCustomControl)this.FindControl("MyCustomControl1");

    myControl.UpdateClassAndMethodName = "ClassName.MethodName";

    //set the addtional public properties for the connection string and the dataset.

    //No need to set the AdditionalUpdateMethodParameters property, it will be null if not used.

    VB.NET------------------------------------ 

    Dim  myControl as MyCustomControl = Ctype(Me.FindControl("MyCustomControl1"), MyCustomControl)

    myControl.UpdateClassAndMethodName = "ClassName.MethodName"

    'set the addtional public properties for the connection string and the dataset.

    'No need to set the AdditionalUpdateMethodParameters property, it will be null if not used.

    Once you've completed building the control, you will only need to wire up the public properties on the parent form and create the update method.  This should save you a lot of time and will give you great joy because you will not have to rewrite the control's code again (maybe just a tweak or two)!

    I had all the keywords color coded, but my session timed out... that will teach me to write a long blog in the web editor. :)

  • Managing session state in the Singleton Model

    Effective management of user state becomes difficult as the application grows during development. Available memory on the server decreases each time the developer decides to persist data in session object. This can have a negative impact on the application’s performance, as well as other applications that exist on the server.

    Available memory is one consideration; however I will be focusing on the benefits of better organization of session objects. If you have not read the following article, do so now http://www.aspalliance.com/robertb/articles.aspx?articleId=4.

    Generally speaking, each page on a web application may have a dataset or multiple datasets providing the data the user will be interacting with. Some of this data may be data that is general to the entire site; some of it may be specific to the page. View state may be one option for page specific data, but that’s a tangent for another time. What if you have a series of forms that take the user form point A to point E while collecting data from points B, C, and D in-between, such as a wizard assisting a user in filling out an employment application? What about a shopping cart that is available for the user while they are browsing different areas of the site? You may have created several different datasets, one for each page, maybe a few other objects to handle one-off bits of information, whatever the case, you may have ended up with ten, twenty, or thirty or so objects in session. What if you needed to clear out or test specific objects being stored in session and there are a dozen or so objects persisted? With the Singleton model, everything can be typed allowing you to access those objects using intelisense.

    I recently deployed a management application that handles the admin tasks for all .NET deployed web apps for a certain client. This application handles users, roles, role memberships, as well as various application specific areas. When the user logs in to the management system, they must select a server, which provides a list of applications. The user then chooses an application to administer. This information is stored in one singleton object, and is made available to every page.

    Below is a portion of my session object:

    using System;

    namespace CSharpWeb
    {
    ///


    /// Manages Session Objects
    ///

    public class SessionManager
    {
    //Make the constructor private
    private SessionManager()
    {}


    //Name of the session variable
    private const string SESSION_MANAGER = "SESSION_MANAGER";
    string _userName = "";
    string _firstName = "";
    string _lastName = "";
    string _selectedAppConString = "";
    string _server = "";


    //For brevity, only the below public property is displayed...
    //you get the idea, one public property for every private member.
    public string UserName
    {
    get
    {
    return _userName;
    }
    set
    {
    _userName = value;
    }
    }


    ///


    /// Gets the SessionManager object out of session and returns it to the caller.
    ///

    /// Session Manager typed object
    public static SessionManager GetSessionManager()
    {
    SessionManager sMngr;
    if(System.Web.HttpContext.Current.Session[SESSION_MANAGER] == null)
    {
    sMngr = new SessionManager();
    System.Web.HttpContext.Current.Session[SESSION_MANAGER] = sMngr;
    }
    else
    sMngr = (SessionManager)System.Web.HttpContext.Current.Session[SESSION_MANAGER];

    return sMngr;
    }
    }


    ///


    /// Calling class, this could be a class, but normally would be the WebForm itself.
    ///

    public class CallingClass
    {
    public CallingClass()
    {}
    ///
    /// Call here to retrieve relevant data from the data source.
    ///

    public void FillData()
    {
    //Get the data out of session
    SessionManager sMgr = SessionManager.GetSessionManager();
    //Make the calls here to retrive the relevant data:
    sMgr.UserName = "Retrived user's Name Here";
    //Set other properties of the Session Manager.

    /*
    No need to put the Session Manager "Back Into Session." This is handled
    because the object is in the Singleton model; the GetSessionManager() method
    is static and the reference to the object in session is maintained.
    */
    }
    }
    }

    This is just a very small subset of the actual class, but I think my point has be made. You can easily extend this class to include typed datasets, additional properties, etc.... I now have available to me the currently logged in user’s information, the selected application’s connection string, and whatever other luggage may be necessary to carry around.

    I have used this to maintain the current index of a DataGrid, handled a return to previous page, and managed the drill down into child pages. There are plenty of possibilities. This class could even be extended to allow for multiple session managers across the site, each having their own area of responsibility.

  • Brand Spankin New

    Wow, this is exciting. I've been reading posts for some time, and recently Darrell Norton started to blog. (Darrell is co-founder of WeProgram.NET, along with Grant Killian and myself). Now Grant and Paul Laudeman have started blogging. I have had the distinct honor of working with all three of these guys, they really know their stuff.

    Well, I am off to eat some pizza. My wife is wrapping up her softball season with a final get-together.

    My first post of substance will be on Singleton Session, you can read the following article HERE , its pretty self explanatory, but I will examine this in a bit more detail, and go over my implementation of this in my last project.

More Posts

Our Sponsors

This Blog

Syndication

News