Here is a basic refresher on value types, reference types, and collections. The following program executes without any assertions failing. Object.ReferenceEquals determines whether the specified Object instances are the same instance. Good stuff to know before an interview.
Update: note John's comment to my post:
To say "myValueType1 and myValueType2 DO NOT point to the same object" is a little bit misleading, because myValueType1 and myValueType2 are just different memory regions on the stack, they're not really 'objects', they're most certainly not 'object references'. The process of passing them as parameters to ReferenceEquals causes them to be boxed (thus becoming 'objects' on the managed heap (complete with object header and GC servicing) with the data from the stack copied into the object on the heap). Another reason why "myValueType1 and myValueType2 DO NOT point to the same object" is a little misleading is that myValueType1 and myValueType2, by virtue of being value types, are not 'pointers', they don't point anywhere. It is true that the value of these value types is stored at different memory addresses, but that's trivially true as the implication of them being local variables.
Here we are at the start of a new year. For many of us, this is the time to plan and budget for the coming months.
One thing is obvious; Microsoft will give us plenty of choices. For example: Which Visual Studio Product is Right For You? Well, it’s a tough choice. My co-workers know me as a Brian, but there is the occasional Saturday night when I want to be a Charlotte.
You also have to factor in your options if you are a Microsoft Partner, and later this year we may choose between 20 Windows Vista SKUs.
The problem is, we don’t like choices. We like answers better. Solid answers based on quantitative analysis. Because of this, I spent the holidays doing some mathematical modeling and trying to devise a formula to make technology purchasing decisions. Here is what I came up with:
Now, for the simple definitions:
n is the number of developers you work with.
x is a value to assign to each developer. Assign a value of 2 if the developer primarily works in C#. Assign a value of 1 if the developer primarily works in VB.NET. Assign an arbitrary imaginary number if the developer primarily works in J#.
b is the amount of time (in seconds) it will take a photon to traverse all of your developers laying head to toe.
y is the number vertices on the organizational chart between you and the CEO.
t is amount of time it would take for you to fly to Seattle, Washington, assuming a snowstorm in Chicago, fog in London, and no flight delays in Cairo.
m is the mass, in kilograms, of all your source code printed on 10.5 lb smooth finished 8.5’’ x 11’’ paper.
The only problem is, I’ve yet to interpret the number the formula spits out. I’m hoping some bright people on the web might see this, and help out, because then we'd all know exactly what to do...
Just figure out what the following program writes to the console...
Who is gonna port this to VB?
There are a couple articles on the web saying you can use a base Profile class like so:
Then use the inherits attribute in web.config like so:
I hope I can save you some time by pointing out the above setup doesn’t work.
You’ll find the HttpContext contains a non-null Profile object, but SQL Profiler will confirm that ASP.NET never populates the object with data from the database. Perhaps the above approached worked in pre-RTM bits, I’m not sure.
Here is a CustomProfile that will fetch and save data properly:
With the above class, Profiler shows the expected “exec dbo.aspnet_Profile_GetProperties” and “exec dbo.aspnet_Profile_SetProperties” commands and it all works as expected.
ASP.NET uses a lazy-load pattern for the Profile object. The runtime doesn’t touch the database until execution first reaches SettingsBase.GetPropertyValueByName (SettingsBase is the parent class of ProfileBase). GetPropertyValueByName will ask the Profile provider to fetch all properties from the database.
The good news is, if a web form doesn’t use any Profile properties, you don’t pay the overhead of a database hit.
New article on OdeToCode: Profiles In ASP.NET 2.0
One good reason to inherit from a custom base class is that we can add additional logic to the Profile object. For instance, we can add validation logic to the Age property to ensure the user provides us with a sensible age, and not a value like 443.
If I go to the trouble of designing multiple ASP.NET Themes using skin and css files, chances are I will let a user choose the theme they find most pleasing. To let the user choose a theme, I’d first have to know what themes are available….
I could maintain the list of available themes in a configuration file, or in a database table. When I add new themes, I’ll have to update the file or table. A better design would be for the application to figure out which themes are available auto-magically, perhaps by using a class provided by ASP.NET….
Digging around, I find the IThemeResolutionService interface and it’s GetAllThemeProviders method. Each ThemeProvider encapsulates a theme. Unfortunately, the service appears to be available only at design time.
Due to the dynamic compilation features in ASP.NET, I figure there is no foolproof way to see all available themes. Even if I reflected every Type in the AppDomain, some themes may still be left on disk and un-compiled. Themes … on disk …
A simple solution would just look at what directories are available underneath the App_Themes directory. Without any error checking, the code would look like:
The above code seems fine until I start thinking about how it could break. It occurs to me that the ASP.NET plumbing doesn’t look directly at the file-system, but sees files and directories through virtualization goggles. There is probably a safer way to write the code, just in case the themes live in a database, or get pre-compiled away….
Now, I’m cooking with oil and a bottle of sherry.
Except … the rumors of the demise of global themes have been greatly exaggerated…
At some point in the preview builds of ASP.NET, Microsoft shipped a couple global themes. Although the themes themselves were dropped around beta 2, the ability to define global themes for all applications still exists. See the bottom of “How to: Define ASP.NET Page Themes” to setup global themes under WebDev and IIS.
Although I found it possible to get to the global themes directory using the VirtualPathProvider and HttpRuntime.AspClientScriptVirtualPath, the solution was beginning to feel a bit clunky. Also, since global themes live outside an application’s home directory, there is no way to read the available theme directories when running at medium trust. (The themes are still available to skin a page, however).
Finally, I’ve arrived at…
Go back to plan 1 … or plan 4.
I was going to write a short blog post about event order when a MasterPage is present, but I found MSDN covers the topic well: “Events in ASP.NET Master and Content Pages”. Notice the MasterPage’s Init event will fire before the content page’s Init event, but the content page’s Load event fires before the MasterPage’s Load event.
Sound confusing? Well, the MSDN doc offers advice in a declarative form: “The sequence of events in master and content pages rarely is important for you as page developer”. If you find the order of events is important, you might be tightly coupling your content pages and master pages and sliding towards a type of “Master Page Anti-Pattern” design. Keep the two entities loosely coupled with custom events, and maintainability improves.