ASP.NET globals?? (general architecture help)


Hi, I am brand new to ASP.NET, and even web development.  I am trying to write an application that allows the user to manipulate a server database, and I've been following the walkthroughs and have had moderate, although hard-fought, success.  I am using VB ASP.NET.

Now that I am successfully reading and writing data using SQL connection, DataGrid, etc (using the walkthroughs)., my instinct (being a normal windows developer) is to write a mydatabase class to encapsulate the work that needs to be done to initialize, terminate, query for or update my specific tables, etc; and to have my various pages call to this class when it needs to use the data (I'll have 5-10 pages on my site that need to look up or update a variety of data in a variety of ways).

Is this the right approach?  Is it even possible to have an app-wide global object (my proposed DB class) that is always there?  I see how I can create a class (project->Add class), but I actually don't see how to reference it from the codebehinds of any (much less all) of my pages.

Anyway, any thoughts on how to architect a database-interactive VB ASP.NET site would be helpful.  I'll spread the points around to any useful answers.  Thanks a lot!
riceman0Asked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

margantCommented:
There are several objects you should look into:

Session - per user.
x="testdata"
Session("lala")=x

Cache - global caching object. Great to save anything and it has expiration dates. Very manipulable so i recommend it even for the session base as long as you cache with unique name and then expire in a reasonable time. For complex objects you can even put something like a dynamic table into the cache and then load it back from cache into a datagrid on the other page.

Application variable - per application (basically unless you reboot IIS the variables are going to be there). Good for application configs but not page operations.

Hope that helps,
A.M.
Kevin CrossChief Technology OfficerCommented:
Sounds like proper object oriented code to me. :)

You would compile your class into an assembly and then from asp.net pages or their codebehind use the import directive then you can use class in code.

Codebehinds can be referenced from the Page directive I believe using the Inherits  and Codebehind properties.
<%@ Page language="vb" Codebehind="CodeBehind.vb" Inherits="Namespace.CodeBehindClass" %>

If you are trying to achieve all pages using one class to access database, so it acts as manager and synchronizes requests, etc.  Then you can code your class to be static/single instance or try using global.asax file to instantiate one copy of class for application then pages call to that instance to make calls to database.

:)
Kevin CrossChief Technology OfficerCommented:
Took too long typing...nice post margant
Introduction to Web Design

Develop a strong foundation and understanding of web design by learning HTML, CSS, and additional tools to help you develop your own website.

mrichmonCommented:
>>Is it even possible to have an app-wide global object
Yes but not recommended.

Really what you need to look at is a what is called the 3-tier architechture.  This is where you encapsulate connectivity to the databse in a separate layer.  It is a much more complex architechture, but does what you are asking for in the proper manner.

Baiscally it would be a new class.  In .NET 1 the class would only contain Static functions.

Here is an example:

namespace MyData
{
      public static DataSet GetAllSoftware()
      {
            //your code to get the dataset goes here
      }

}

Then in the backend of the page you would do somthing like this (say if you were binding the software to a repeater)
RepeaterName.DataSource = MyData.GetAllSoftware();
RepeaterName.DataBind();

SO basically anywhere you need to get that same stuff you just call the function in the data layer.

This is avery simplified example, but should give a general idea.  Note how the functions inthe data layer are static...
Kevin CrossChief Technology OfficerCommented:
Thanks mrichmon that is a good example of what I was referring too with static class.  This is the same concept as in Java.  This makes class a singleton (only one instance) and so only one will ever be created no matter how many calls.  

As I said before on updates, you will probably want to synchronize access.
mrichmonCommented:
Yes it looks like the three of us were answering at the same time and the comments appeared in the order based on who finsihed typing first :o)
riceman0Author Commented:

mrichmon, what would be the difference there between class myData and namespace myData?  (I'm using VB, probably something similar?)

And it would just be static functions, meaning I could, or couldn't put member variables there that hold data that all pages could access?
OliWarnerCommented:
No namespaces are groupings of classes... mrichmon just forgot to type a class line in there...

Personally I see no problem in junking things in the application store and definately no reason for using purely static classes... I've done it with fairly large objects and without a problem.

To store:
Dim application As HttpApplicationState = HttpContext.Current.Application
application.Item("varName") = yourObject

To get it back:
Dim application As HttpApplicationState = HttpContext.Current.Application
Dim myObject As MyType = DirectCast(application.Item(varName), MyType)

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
OliWarnerCommented:
Oh but I would make a static method for retrieving this from the application.
That way if can check to make sure that the application space for that variable is null and if so, regenerate it before passing it off to the user. Ala:

    Public Shared Function GetMyObject() As MyType
        Dim application As HttpApplicationState = HttpContext.Current.Application

        application.Lock()
        Dim myObject As MyType = DirectCast(application.Item(APPLICATION_ENGINE_MANAGER), MyType)

        ' If a object doesn't exist here, create one
        If myObject Is Nothing Then
            myObject = new MyType(whatever_constructor_nonsense)

            application.Item(APPLICATION_ENGINE_MANAGER) = myObject
        End If

        Return myObject
    End Function
OliWarnerCommented:
and that's what happens if you copy from existing code >_<

swap out APPLICATION_ENGINE_MANAGER for the application variable name =)
or create a constant, as we did, and use it that way (recommended)
OliWarnerCommented:
Oh something else I forgot to mention... we use locks to stop one person reading or editing something while someone else is reading or editing...

That's the application.Lock()

if that doesnt look like a problem to you, fine, otherwise make another shared (static) function to unlock the application and call this after you're done with the data in your process. Ala:

    Public Shared Sub Unlock()
        HttpContext.Current.Application.UnLock()
    End Sub
riceman0Author Commented:

So OliWarner, that worked well, however locks are necessary to ensure only one user is accessing an application object at a time stored this way?  Is that because it is essentially shared by everone that accesses the website?
riceman0Author Commented:

OliWarner, what would happen if I used the Session instead of the Application, is that legal?
riceman0Author Commented:
Or a context, msdn actually seems to say that's what it's for:

Context Provides access to the entire current context (including the request object). You can use this class to share information between pages. HttpContext
OliWarnerCommented:
>> Is that because it is essentially shared by everone that accesses the website?

Correct. The object that I use in the application variable is real data that other users might use... If you're not doing something that uses this, you shouldnt need to use the locks... it sounds like from what you said earlier that you might need the locks in place, but as you can see, they're pretty simple... Just call the unlock method after you're done with the variable...

If other people come in and require something from the application, the server puts them on hold for a bit but processing time is so low its never noticeable.


Just a quick question though... why does this object need to persist?
OliWarnerCommented:
>> OliWarner, what would happen if I used the Session instead of the Application, is that legal?
Sessions are a per-user variable... Each browser "session" with your site has its own session store which is separate from the others. Its good for storing information about the user or other data just about that one user. Its legal - I'm just not sure why you would want to do that. A session can still be the same for multiple concurrent requests... say the user loads up 15 windows of one page at once, if the object is in the session and you have no locks, chances are you'll end up with things overwriting each other.

Context is just an umbrella class for all things web-related in context.. for example it stores server information, down to the very incoming request. It also stores the application values hence why I use: HttpContext.Current.Application

The reason you have to call it through HttpContext here is because I'm assuming you're deep in a class. When working in a codebehind file these vars are autogenerated. Its like the difference between coding in JSP and servlets. Same language, slightly different rules.
riceman0Author Commented:

The only reason I want the object to persist -- I might have asked this in a confused way -- is because I want information to be the same as a user navigates from page to page on  my site.  for example, the first page is a login screen, which records his information, checks it against a database, and loads up a lot of information about him/her.  If he has permission (per his record in the DB) to go to the edit screen, then he will be able to do so and the buttons on that screen will be enabled/disabled according to his other permissoins.

Having some shared DB info and User info would prevent having to retrieve the data again on each page; his current user info and his last query could remain loaded up in my new class, accessible from each page.

That's it.  Sounds like I might want the session variable?  Can I store my objects in there, too?
riceman0Author Commented:
session seems to work too, I'll go with that unless anyone thinks I shouldn't,

Seems like I'm in business.  thanks all.
mrichmonCommented:
>>namespaces are groupings of classes... mrichmon just forgot to type a class line in there...
Yep I did - typing too fast :o)


Only disadvantage of sessions is that they expire after a time limit, but often this is not a problem.

Good luck
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Web Development

From novice to tech pro — start learning today.