I’m working on an update for my ASP.NET 2.0 compiler utility tonight to integrate the ASPNET_MERGE functionality fromt the VS.NET 2005 Web Deployment Projects into it and while I’m playing around with the tool I’m running into a one snag that I want to pass on here.
VS.NET 2005 has changed how projects work and compile and by default VS.NET assumes everything lives in its own assembly or at the very least in one assembly per directory. When you create a new directory and add say a Default.aspx page to it by default ASP.NET creates something like this:
<%@ Page Language="C#" AutoEventWireup="true"
CodeFile="Default.aspx.cs" Inherits="_Default" %>
Now assume that you have several sub directories in this app and you have Default pages in all of them, all of them with a _Default class in them. If you compile this now inside of Visual Studio or with the ASPNET_COMPILER.EXE all will be well under any of the supported compiler models because these _default classes all live in separate assemblies.
Notice that ASP.NET creates the codebehind classes without a namespace too, so effectively you end up with multiple classes that effectively have the same signature. This works in 2.0 only because the compiler doesn’t actually create a single assembly, but either individual assemblies for each class with a generically assigned namespace, or a single assembly per directory which is also safe because you can’t have the same file in a single directory.
However, if you use the merge utility and you combine assemblies into a single assembly you all of a sudden have a problem because now the names of these files will conflict and you will get errors that a certain type already exists.
I’m usually pretty good about naming my classes cleanly in real apps, but several of my demo projects I use for training or seminars end up using some of these ‘bad’ habits that accept the default behavior.
I think it was a bad idea to pull the namespaces out of the generated assemblies by default. VS.NET creates the codebehind classes without namespaces, unlike VS.NET 2003 which automatically assigned the namespace to match the directory structure rootnamespace + .subdir.subsubdir. This concept still works, you just have to remember to set up the namespaces on your own. I guess the thinking here was that the namespaces are basically useless due to the new compiler models, so they might as well generate them. But with the merge tool it becomes an issue again.
As an alternative you can also rename the classes of course. I think that’s the most sensible idea – it’s not exactly good form to have multiple classes with the same name in the same ‘project’ anyway. You can have multiple default.aspx pages, but use different class names for the codebehind classes.
BTW, you might ask why I am bothering with the compiler tool now that Web Deployment projects are here and I think that the VS.NET tool actually is quite usable and offers some good features. However, I still find myself judiciously updating my sites rather than the divide and conquer approach of completely overriding my application on the server. For this the tool puts everything right at my finger tips.
Also if you're using this on a machine where VS.NET is not available, or if you're using Visual Web Developer it works there as well... assuming you have downloaded and installed the merge tool (not 100% sure what the licensing is actually and whether it can be deployed on a non-VS machine).