Scott,
All valid points.
My only sticking point is the thought that external assemblies can't
and shouldn't reference and web project assemblies.
Yes, I agree.
Let me give you some concrete examples we can debate.
Our 1.1 web project has a configuration and a session class that
provide clean and consistent access to information stored in the
web.config and session state. From a design perspective, that
information is owned by the web application and the web application is
responsible for maintaining it; therefore, the classes are located in
the appropriate component. We have an external class library that
contains custom controls used on pages in the web application. If one
of those controls needs to retrieve a value from session or
configuration, it calls the classes in the web app. In order to
migrate to 2.0, we have to move those classes into separate assemblies.
It seems like a clean design to me.
I think I get what you are saying.
I generally approach these types of problems with a factory type
design pattern and interfaces.
Define an interface (lets call it ISessionManager) in a class Library
(lets call it sessionmanager.dll). The interface could well be an
abstract base class, too.
Next I'd build a custom control library that references
sessionmanger.dll and program against the ISessionManager interface.
That's all the controls need to know - that someone will provide an
ISessionManager as a paramter. No references to the web app are
needed.
The web app references sessionmanager.dll, and the custom control
library - it can use components from either assembly. The web
application derives from a class from ISessionManager and provides a
concrete implementation of that ISessionManager contract. For example,
if ISessionManager has a property called UserName, then the web app
implements that property by retrieving a string from the Session
object (or the database, or ViewState) - the important part if that
the details are hidden from anyone who uses an ISessionManager object.
When the web app needs an object from the custom control library to
perform some action that requires an ISessionManager, it passes along
it's session manager object. The custom control library doesn't need
to reference the web app, or know the exact type that the web app is
using to manage session information - it only needs to know that the
object is an ISessionManager.
Here is another example where the web app can't reference itself
properly. Our 1.1 web project has custom controls. The pages in the
web app have register tag prefix directives that use a strong
reference. The controls are only used by the web project; therefore,
they don't belong in a separate component. In 2.0 the controls end up
in App_code.dll and you can't specify the version or control the
assembly name. It seems that the only solution is to move the controls
to a shared assembly, or keep them in the web app and remove the strong
reference.
1) Versioning and naming an assembly in ASP.NET 2.0
You should be able to do this with a wed deployment project. It
doesn't change what happens at compile time - but the end result can
be a strongly named assembly with an AssemblyVersion attribute
applied.
2) Maybe I'm missing something obvious, if so I plead ignorance
I'm guessing you have a custom control in AppCode derived from
WebControl or Control?
Doesn't the following work (where pcc is your concention and Foo is
your namespace - App_Code is consistently App_Code.dll).
<%@ Register TagPrefix="pcc" Assembly="App_Code" Namespace="Foo" %>