|
|
| D: | Domains | Authors.aspalliance.com | Stevesmith | Articles | Reuse in ASP.NET Across Domains |
|
Reuse in ASP.NET Across Domains ASP.NET offers a wide array of advantages over Classic ASP, which will compel the millions of ASP developers to move to ASP.NET in a hurry. However, as with any new technology, there are tradeoffs. Not EVERYTHING is easier to do in the .NET world, and in fact some things have become more more difficult. Consider a website such as ASPAlliance.com, which provides dozens of columnists with their own web sites to use to write about and demonstrate ASP and ASP.NET. In order to provide a common look and set of functions to these columnists, it was quite easy in ASP to use an include files, which allowed everyone access to these common library functions. ASP.NET provides support for User Controls, a powerful new tool that is functionally similar to include files, but gives developers the ability to programatically control the behavior of the controls (unlike include files). These would seem to be the logical upgrade for the ASP Alliance's include files, but unfortunately this solution will not work. Although ASP include files could be referenced by any website on the server, User Controls cannot. .NET introduces the concept of Application Domains, and does not allow one application to reference controls found in another application's domain. This means that, while the root web of ASPAlliance.com might be able to take advantage of User Controls, the columnists' webs would be unable to do so. This is a fairly large problem, since it is important that the site be able to offer these common tools and look and feel to all of its columnist websites. Of course, that's not the end of the story. There are several options available to overcome this problem. The first and simplest option is to simply copy the User Controls to each columnist website, so that they can be referenced without crossing Application Domains. While this approach might be relatively simple and easy to implement at first, it would quickly become a maintenance nightmare as changes occurred in the User Controls and as new columnists were added to the site. This option would not be ideal. Another option to consider is to use a shared component. There aren't too many of these floating around today, but by this time next year these component should be commonplace. Basically, a shared component is installed at the computer level, and is accessible by any application on the computer (it can be restricted, but that's another story). However, because they are shared, these custom components need to be given a strong name, which is accomplished through the use of the 'sn.exe' application included with the .NET SDK. This uses encryption to ensure that the name of the shared component will not conflict with the name of any other shared component, and in this way it is functionally similar to GUIDs in current Windows DNA programming. Since I haven't as yet written any strongly named components, I was a bit leery of this solution, because I didn't know how hard it would be to do. So far, though, this looked like the approach I would need to take, and was recommended to me by the Microsoft .NET team.
Thinking about it some more, though, I hit upon what seems like an obvious solution now. Web Services. See,
recently ASPAlliance.com has linked up with several other organizations and has spun off one organization of
its own, each with their own web sites, and not only would this solution allow columnist websites to use the
library functions and look and feel of the Alliance site, but it would also allow these other websites to do
the same thing. Essentially, this would kill two birds with one stone. For those of you are who are not yet
familiar with Web Services, I recommend reading about them here: There are some down sides to using web services in this manner. First of all, there is the obvious overhead -- any page that uses a web service to get its layout is essentially going to use an extra web request (or two if it has a header and a footer it gets as separate methods) every time it is requested. This sounds like a big deal until you realize that a typical page with a handful of images and perhaps a CSS or Javascript reference has as many as a dozen or more separate requests already. The second issue is performance. Especially when the server has just started, the web service is going to be slow to respond. A wait time of 10 seconds is not unreasonable (and is in fact what I'm using here). If two of these requests were required on every page, obviously performance would be atrocious. To this I have one thing to say: caching. We're talking about relatively static page layout here -- a perfect candidate for caching. I cache it everywhere. I cache my template pages that hold the layout for my web service to grab. I cache it at the web service level itself (each Web Method). Sometimes I integrate the navigation into a user control and I cache the user control. And of course, I enable Output Caching on nearly every ASP.NET page on my site, simply because it dramatically increases the performance and scalability of the site. For more on caching, you can read my overview of output and fragment caching. Now, having come up with the high-level solution to my problem (since I run the ASP Alliance, it was MY problem, after all), all that remained was to flesh out a few details. How would I organize the services? How would columnists and other websites take advantage of them? How would I make them easy to manage, since they are compiled code without a GUI, and therefore not as easy to build as User Controls or Web Forms. To answer these in reverse order, here is what I have one and plan to do:
I recently had a reader (Paul Jenkinson) suggest to me another way to attain reuse of User Controls across application domains in ASP.NET. It requires a bit more server access (or ADSI coding) than using web services as I have described, but otherwise seems to be a cleaner solution (except it doesn't allow other sites to use the controls, but that may be preferred anyway). Anyway, here is Paul's suggestion: I have been thinking about this article and have found an alternative solution, you may have already discount this, if so I would like to hear your reasons. This is the scenario :1) You have a number of web applications set up in IIS: webapp1: points to local folders C:\myweb\app1 webapp2: points to local folders C:\myweb\app2 webapp3: points to local folders C:\myweb\app3 2) webapp1 contains a normal folder named 'shared' which contains a number of user controls or other content you want to share with the other web applications. The shared folder exists on the local hard drive in C:\myweb\app1\shared, this is the master copy and does not exist on the local hard drive for webapp2 or webapp3. 3) To share the content, use IIS manager to set up a sub virtual directory named 'shared' under webapp1 and webapp2 which points to C:\myweb\app1\shared. More Other Options (added 31 October 2001):Building on Paul's solution above, another reader (Scott Catharall) added this: The following are the steps (tried and tested) involved in sharing user controls from a single location for many web applications using .NET. The compilation of these steps was due to a collaborative effort between John Casagrande, Scott Catherall, Reed Comire and Richard Evans all from USC. Inspired by the article by Steven Smith who referenced Paul Jenkinson who in turn suggested that this should be possible. Step 1: Create a web application project. This project should contain the user controls to be shared by other applications. For this example we use the name "Common". Create and build user controls from this project. In this example we will use "MyControl.ascx". Step 2: Create a virtual directory in each application that will use the shared user controls. This is done using the IIS manager. For this example the application is "App1". From within IIS right click on the "App1" application, select New>Virtual Directory. Browse to the "Common" application. In the example we name the virtual directory "Common". Step 3: Create a reference from the using application to the shared application. For example from the "App1" application project within Visual Studio, create a reference to "Common". Right click the references folder in the solution explorer. Select "Add Reference", then "Browse" to the "Bin" folder of the shared application and select the dll. In this example we browse to c:\inetpub\wwwroot\common\bin\common.dll. Step 4: To use the user control on a page in the using application register the user control. For this example we use the user control in "MyPage.aspx" in the "App1" application. The first line of the aspx page is <% register ... src="common\MyControl.ascx" %>. Step 5: Finally, in the code behind set the type for the user control. In this example we insert the line Protected WithEvents Control1 As Common.MyControl If in your user control you use namespace then the line would be: Protected WithEvents Control1 As Common.MyNamespace.MyControl The only drawback we see using this method is that you cannot use the Visual Studio GUI for dragging and dropping the usercontrol onto your aspx page. SummaryWhen all is said and done, YOU could consume the look and feel functions exposed by ASP Alliance, if you wanted to do so. Relationships with third parties such as ASPIN.com and http://jobs.aspalliance.com/ involving separate websites will be easy to build while maintaining a unified look and feel for the site. Although this started out as a disadvantage of ASP.NET (the inability to share User Controls), in the end the solution to the problem will provide much more value than was possible with Classic ASP. |
|
|
|
|
|
|
|