I’m trying to move past the subject of ASP.NET 2.0 compilation to something new, really I am, but between some insightful questions I’ve seen, and work on my own code, I’m starting to have … issues.
Let’s say you have a web form and need to dynamically load a user control. The code inside a web form might look like:
{
Products products;
products = LoadControl("Products.ascx") as Products;
products.CategoryName = "Blunt Instruments";
Controls.Add(products);
}
We can build the code from the IDE with no errors. We can do a simple precompilation from the command line with no errors. There are errors, however, if we add –fixednames during precompilation.
Ouch.
When building from the IDE, the runtime was batch compiling all the aspx and ascx files inside the root directory into a single assembly. With –fixednames each aspx and ascx compiles into a separate assembly. The precompiler doesn’t know where the Products type lives now - there is no reference.
What we should have done from the start was use an @ Reference in the ASPX like so:
<%@ Reference VirtualPath="~/Products.ascx" %>
The point isn’t how to make things work, the point is we wouldn’t have these idiosyncrasies if the compilation model was simple instead of complicated.
The first hint of trouble should have come when typing in the code to interact with the user control. There is no Intellisense. Why? Because there is no real "project" for a web project. Pick one of the following perspectives on this fact:
One way to view the 'project-less' project is to picture each webform as an island – an autonomous service whose type is unknown outside it’s own declaration. Each web form can end up in a distinct assembly. No one webform knows anything about any other webform. This perspective is pleasant.
A second, less flattering view of the 'project-less' project is how a web application is no longer a cohesive unit, but a random collection of whatever known files the IDE can find inside your folders. Point the IDE to a folder, throw anything in, it will compile when the time comes. It feels sloppy.
If you do need to share secrets between webforms, you need to use the aforementioned @ Reference directive. For example, when someone needs to pass values between web forms, they often find the following article on MSDN: Passing Server Control Values Between Pages. I’ve never liked this approach – it has the aroma of an anti-pattern. The approach will also not compile in ASP.NET 2.0 unless you @ Reference the first web form with a Virtual Path from the second (transfer target) web form.
There is at least one other migration scenario where this can sting. Let’s say you have stand alone .cs or .vb file in a 1.x web project. From within the class you use a second class that is a code-behind class for a webform. I don’t advocate this approach, but I can understand some scenarios where it would be useful.
The 2.0 migration wizard will move the stand alone source file into the /App_Code directory, and the code will compile into the App_Code assembly. Types inside the App_Code assembly will have no knowledge of any code behind classes - you cannot get to them. There is no easy way to get this scenario to work in Beta 2 without injecting an abstract base class for your webform code-behind class into /App_Code.
To solve this, the ASP.NET team decided to automatically generate stub classes for code-behind classes into the App_Code directory in post-Beta 2 builds.
I feel like I’m studying a Rube Goldberg machine.
Comments
If multiple folders is bad, we will avoid them. If multiple web forms is bad, we will avoid them, too. Or leave just one as the front controller.
We will use VS for it's intellisense. If we dig static typing and/or generics, then we stick with C#.
But I really can't see why we all wouldn't jump on the RoR band wagon.
Microsoft has gotten a lot of flak over the inability to access other pages and user controls and it looks like they are once again changing the way this works (according to a response I got on the Whidbey forums). The Microsoft person wasn't specific, but it sounds like code behind files will end up in App_Code, and then become part of the main assembly, to which you can cast.
Has anybody checked out June CTP to see if this has been implemented?
-fixednames? why would I want every webform to be a seperate assembly?
Here is one line from your article
"The pre-compiled code will end up inside of the Temporary ASP.NET File directory, just as it would when the runtime compiles files for a browser request. Inside of the bin directory for the compiled site, you’ll find the assemblies (dll files)."
I precompiled the site with this command
aspnet_compiler -v /website1
It generated precompiled code in Temporary ASP.Net folder but it didn't created any bin folder as u mentioned(it does that when i precompile for Deployment)
There is one more strange behaviour i observed.
When i requested the default.aspx for the first time then it created one child node bin inside website1 (it is not directly visible in IIS console but if u acess it programatically using DirectoryServices like this
de = new DirectoryEntry("IIS://localhost/W3SVC/1/Root/WebSite1/bin");
PropertyValueCollection pvc = de.Properties["Path"];
Response.Write(pvc.Value);
It didn't returned any physical path but it exists.
So whats the significance of this?