Problem with runtime compilation of aspx files. Register Directive ignores Assembly

D

Dan

Hi,
I have a problem using an aspx page with a Control on it. I get the
following error message

Compiler Error Message: CS1595: 'Test.Class2' is defined in multiple
places; using definition from
'c:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\Temporary ASP.NET
Files\root\1f575646\ad3a161b\assembly\dl2\57ca505e\044565c0_f84fc401\Test1.DLL'

The problem is that the control is defined in two different assemblies
(with different names) but with the same namespace.
I really need this in my setup so I wonder why it doesn't work.
The thing is that it does work if i Create the Control in the code
behind instead of the aspx file.

My real question is why the heck does the runtime compiler ignores the
Assembly attribute that is specified in the Register directive? It
seems that the runtime code generator only looks at the namespace
attribute and ignores the Assembly that is specified... (or what it is
else for?)

<%@ Register TagPrefix="Test" namespace="Test" Assembly="Test1"%>


Is it possible to get rid of the /warnaserror flag that is passed to
the csc.exe when the dynamic dll is compiled?



To reproduce the behaviour:

Create a asp.net project with a webform. (WebForm1.aspx)

Create a Class Library project (Test1) and add the following class
file.
##########################################################################
Class1.cs
##########################################################################
using System;
namespace Test {
public class Class1 {
}
}
##########################################################################

Create a Class Library project (Test2) and add the same class file as
above.

Add the Test1 and Test2 projects as references to the asp.net project.

Modify the WebForm1.cs file and add an instance field to the class of
Type Class1
##########################################################################
WebForm1.cs
##########################################################################
using System.Web.UI;
using Test;

namespace localhost {
/// <summary>
/// Summary description for WebForm1.
/// </summary>
public class WebForm1 : System.Web.UI.Page {
Class1 Class1 = new Class1();
}
}

##########################################################################
Compile. You will get a warning that the Class1 is found in multiple
places, but the compiler will choose one and go on and create the
output.

Step 2:
Create a webcontrol and add it to projects Test1 and Test2

##########################################################################
Class2.cs
##########################################################################
using System;
using System.Web.UI;
namespace Test {
public class Class2 : Control {
protected override void Render(HtmlTextWriter writer) {
writer.Write("Class2");
}
}
}
##########################################################################

Modify the Webform1.aspx to add an instance of the Class2 to the page.
##########################################################################
WebForm1.aspx
##########################################################################
<%@ Page language="c#" Codebehind="WebForm1.aspx.cs"
AutoEventWireup="false" Inherits="localhost.WebForm1" %>
<%@ Register TagPrefix="Test" namespace="Test" Assembly="Test1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
<HEAD>
<title>WebForm1</title>
</HEAD>
<body>
<form id="WebForm1" method="post" runat="server">
<Test:Class2 id="Class2" runat="server"/>
</form>
</body>
</HTML>
##########################################################################

Recompile and go to WebForm1.aspx in your browser.

You will get an Error message like the one below

Compiler Error Message: CS1595: 'Test.Class2' is defined in multiple
places; using definition from
'c:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\Temporary ASP.NET
Files\root\1f575646\ad3a161b\assembly\dl2\57ca505e\044565c0_f84fc401\Test1.DLL'

To try the thing that works,
Modify the Webform to
##########################################################################
WebForm1.cs
##########################################################################
using System.Web.UI;
using Test;

namespace localhost {
/// <summary>
/// Summary description for WebForm1.
/// </summary>
public class WebForm1 : System.Web.UI.Page {
Class1 Class1 = new Class1();
protected override void CreateChildControls() {
base.CreateChildControls ();
Class2 c = new Class2();
c.ID="class2";
Controls.Add(c);
}
}
}
##########################################################################
and
##########################################################################
WebForm1.aspx
##########################################################################
<%@ Page language="c#" Codebehind="WebForm1.aspx.cs"
AutoEventWireup="false" Inherits="localhost.WebForm1" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
<HEAD>
<title>WebForm1</title>
</HEAD>
<body>
<form id="WebForm1" method="post" runat="server">
</form>
</body>
</HTML>
##########################################################################

Now you will get another compile warning but it will compile...

Best Regards
/Dan
 
N

Natty Gur

Hi,

as I see it the only diff between two cases is that in Page Compilation
time when control declared on page and /warnaserror set you get compile
error while trying to do it on page code behind end up with warning. You
can set Page compilation settings by playing with Compilation tag
(http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpgenr
ef/html/gngrfcompilationsection.asp).

But I can't see way you need to declare same class name within same
namespace name. The all idea behind namespace is to let you declare same
classes name but under different contexts. Now you are trying to twist
this behavior...

Natty Gur[MVP]

blog : http://weblogs.asp.net/ngur
Mobile: +972-(0)52-8888377


*** Sent via Devdex http://www.devdex.com ***
Don't just participate in USENET...get rewarded for it!
 
G

Guest

Hi Natty,

I checked the compilation tag, but to no success.

I really wonder why the runtime compliation engine adds too many dlls in the compilation string. For example:

If i remove the Test2 reference from the localhost project, all compilation warnings are removed and runtime compilation succeeds.

But if I add a copy of the Test2.dll to the bin folder of the webserver and recompiles/restarts the webserver (so the runtime compilation is redone) the error occures once more.

This I find quite erronious. Shouldn't the runtime compilation only look at the inheritance info from the aspx file
<%@ Page language="c#" Codebehind="WebForm1.aspx.cs" AutoEventWireup="false" Inherits="localhost.WebForm1" %>
<%@ Register TagPrefix="Test" namespace="Test" Assembly="Test1"%>

and see that the references needed are the localhost.WebForm1 type that is defined in the localhost.dll and look up its references (includning references that the referred dlls referes to) PLUS the Register option that defines the Assembly Test1 to include in compilation.

This is not the case though since this experiment fails...
If I look at the compilation string that generates the error message (or warning) I see that the list contains all dlls contained in the bin folder...
If I add more dlls to the bin folder, all of these are added as well....

Is there an explanation for this behaviour or is it just a easy way of getting most of the references right?

/Dan
 
G

Guest

Hi,

I might add why I need the duplicate of namespaces in the dll:s.

I am creating modules for a web content system and these are installed ontop of an existing platform.

I have a common class library for all of the modules (lets call it Core.dll) and changes in this library is made from time to time and it is not sure that the changes maintains binary compability.

If module 1 (assembly m1.dll) is shipped, I used to ship it alongside with the Core.dll. The assembly files are copied into the webservers bin folder.

If i later ship module 2 (assembly m2.dll) and include a new version of Core.dll that not is binary compatible, problems occurs for the systems that already has m1 installed.

My thought for the module shipping is that we collect the classes that is needed for each module in an separate assembly m1.core.dll and ship it with the module m1.dll.
This works remarkingly well since we keep the assembly sizes down and doesn't have to be binary compatible between the modules. All class files are linked in sourcesafe so all changes in the core library automatically gets included in the next release.

The only problem so far is the runtime compilation that seems to add all asseblies in the bin folder instead of only the referred ones (see sibling post).
This means in effect that I get duplicate definitions of some classes in m1.core.dll and m2.core.dll etc.

Is there a possible way if i make the m*.Core.dll a static library and adds it into the GAC? any toughts about that?

/Dan
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,022
Latest member
MaybelleMa

Latest Threads

Top