Asp.net程序的Master_page模式

来源:互联网 发布:淘宝商品下架了怎么办 编辑:程序博客网 时间:2024/04/28 11:32

Introduction

This article is about detailing processes involved during Framework developments, and as an example, develops a very small framework “Master-Page Framework” using ASP.NET and C#. You will be explained about the object oriented design methodology using UML, Design patterns involved in the Frameworks, and a little about the Pattern Oriented Architecture and Design (POAD), a little bit of everything.

Master Page Framework Development:

Every thing starts with a use case in Object Oriented Software Engineering. One of the use cases while we develop web application is that “User needs a consistent look and feel, through out, period”.

Now what a deal??? We see every day, every where, consistent web-sites etc., etc… We see good-looking “sexy” web sites, but we don’t see one thing (well! you can’t see that), how much maintenance cost is required if we need one change for the whole of the web site. Look's a big deal now :).

Apart from some CSS style-sheet for consistency, what else we need, a framework, Master-Page Framework, which should be extendible, easy to use, pluggable and modifiable visually! (Sounds great! what a wish :)) There is no such thing existing in ASP.NET (Whidbey, does have one, but still long way to go).

I started looking around the web and found some interesting articles:

  • Master Your Site Design with Visual Inheritance and Page Templates by Fritz Onion.
  • ASP.NET Page Templates - Using Inheritance by Peter Provost.

These articles are very good starting points, so I took the entire valuable advises from them and went further, since, I was looking for something like a reusable/extendible Framework. I took the responsibility of redesigning the whole wheel that never existed, in the first place, how is that ;).

The approach I took, what I devised is, Pattern Oriented Architecture and Design (POAD), not design patterns, they are different. I call it POAD because my application has a peculiar look and feel that it follows a pattern. POAD means you have entire prototypic pattern, your application will follow, but will be overridden later for concrete structure of it (the concept needs a whole article and I would write later, with some examples, hopefully next month). So the master-page has header, footer, navigator, menus/submenus, and content place-holders that would be filled in later as needed for concrete pages, How’s that, sounds good. Let's move further! Here are the steps involved in designing the POAD based softwares.

  • Draw the whole abstract pattern your framework would provide.
  • Find Objects responsible for doing the job.
  • Find relationships between them.
  • Find design patterns needed.
  • Elaborate Objects while designing them, and find functionality for them.
  • Write test cases.

Steps Involved:

Draw the whole abstract pattern your framework would provide.

Here is the prototypic pattern of our Framework:

Figure 1 (Master-Page Layout/pattern)

Master Web User-Control

If we decompose this pattern into objects, it’s being clear that we should have something like skeleton or template for the place holders, i.e., there should be something like a master-page that is composed of the placeholders, like header, footer, logo, menus, navigator, and contents etc.

Since our plan is to change these place holders visually, we could safely put these place holders in a user control (PageUserControlBase) that in turn contains all the place holders. Call it a Master user-control, where you define your layout for these contents. Now, our model would have a Master Page that in turn is composed of Master User-Control (PageUserControlBase) that in turn is composed of placeholders, like this:

Getting closer, great! :) Now the visual part is decided that we provide using user-control or so. We want this user-control to be pluggable at run time, so we’ll dynamically load it at run time using web.config like this:

<appSettings>
   <add key="MasterPageUserControl" value="MasterPageUserControl.ascx"/>
</appSettings>

Our Framework encapsulates all the functionality of the Master User-Control (PageUserControlBase) class in an assembly as a base/abstract class, so that we can extend it in future, if we need it. Here is how it would look like:

With this approach, if in future, we decide with some other look and feel of the master user control, all we need is to extend PageUserControlBase class and use it:

<%@ Control Inherits="Shams.Web.UI.MasterPages.PageUserControl" %>

Or use it like this:

<%@ Control Inherits="Shams.Web.UI.MasterPages.PageUserControlExtra" %>

PageUserControl or PageUserControlExtra, will provide us access to the WebControls.PlaceHolder(s). Here is how the PageUserControlBase.ascx should look like:

This was straightforward, right? Yes, it is. Now the visual component can easily be extended, and further, is pluggable through the web.config, and is ready. So while designing the Framework, we are right on target, extendible and pluggable Framework, great :). What else would be needed, well lot of work still there? All we have done so far is we provided a consistent look and feel through pluggable Master User Control-Base. We have a long way to go. Let's first analyze how the HTML/aspx page looks like:

You can see the page itself has four parts, let’s examine them closely:

  • Part A: - HTML Header, describing code-behind language, Page title, Meta info, and HTML body etc.
  • Part-B: - Form area.
  • Part-C: - Master User-Control area, [or any controls].
  • Part-D: - HTML footer area.

Master Custom-Control:

Every page can have one and only one HTML Form. We put all the server-controls in this form (part-C). So, what we need is another object that would encapsulate all these HTML-Rendering stuff shown above, like Part-A, Part-B, Part-C, and Part-D in it. If you look at the Control class, it has all the functionality we are looking for. The Control is a composite that means we can put other controls in it. So, it would be a good starting point to start with a Custom control by extending the Control Object. This extended Custom Control, we named it PageControlBase, will provide HTML rendering capability as well as it would have a System.Web.UI.HtmlControls.HtmlForm object. This Form object would be used to add our famous master-user-control or Part-C in it. Now, our master page would be composed of some master custom control, and master-user-control. Here is the UML diagram that demonstrates all these:

Now that we have a pluggable Master-User-Control, a custom control that will create all of the HTML parts is necessary.

What we need is an integrator class that will insert Master User-Control into Custom control form and attach it to the Master-Page. And that’s the MasterPageBase class, derived from UI.Page class:-

Design Patterns used in Master-Page Framework

When you are planning for any Framework that is based on some prototype or follow POAD, the most effective pattern is the Template design pattern. Here is the code that demonstrates this pattern:

public interface IPageControl
      {
            System.Web.UI.Control ParentControl();
 
            void HtmlRenderStarts();
            void PreHtmlRender();
            void HtmlRender();
            void PostHtmlRender();
            void HtmlRenderEnds();
 
            /// <summary>
            /// The title page can be set with this property
            /// </summary>
            string PageTitle
            {
                  get; 
                  set;
            }
            /// <summary>
            /// </summary>
            string MetaInfo
            {
                  get; 
                  set;
            }
      }

We defined the sequence/pattern of execution that would later be overridden by the derived classes.

Template Design Pattern is used in two occasions:

  • Defined template in the Custom control:-

  • And here is the other place where the same design pattern is used:

Other patterns that are used are Factory and Composite Design Patterns. The Factory pattern is used to create classes, and should provide one place; if we have plan to put some business logic around their creation, we can do it, without breaking the existing code.

Composite Pattern is built in with the .NET Framework, like Control Class is itself based on composite pattern. Composite Pattern in its simple form is a list of list of objects. Instead of reinventing my own containers for objects, I used the Control class as my starting point.

So that’s it, we are done with the Framework. All you need is to derive your page from the MasterPage class, and override the stuff you want to change in your concrete classes. How we do it is shown using UML Diagram here:

Let’s discuss some typical scenarios we’ll come across while doing implementation:

1. Creation of Master Page Skeleton: -

As discussed earlier, all we need is to derive from MasterPageBase. Here is the code snippet as an example:

Here is the output we’ll get; it’s a master-page skeleton.

The visual settings are from web.config, i.e.,

<appSettings>
  <add key="MasterPageUserControl" value="MasterPageUserControl.ascx"/>
</appSettings>

If you have some other-layout in your mind for your MasterPage, you can create your own user control and change the signature in the web.config.

Here is the not so detailed objects sequence diagram, for the above scenario:-

2. Creation of MasterPage from MasterPage Skeleton:-

We would create a MasterPage class from MasterPageBase and override the placeholders with our own UserControls. Here is the example code snippet for this:-

Here is a Master-Page I created for my sample website:

3. Creation of your own pages from MasterPage you just have created.

All you need to do is make this MasterPage class a base class for all of your pages, and override the functionality that you might want to be different, and make things consistent:-

Here is the proposed UML diagram for the rest of the pages for the web site:-

4. If you have more than one Master Pages (MDI Scenario)

In this particular scenario, you would override the function LoadPageUserControl(), where the framework is dynamically loading the user specified master control. Here is the code snippet for this scenario:-

And here is the UML diagram for representing this scenario:-

Here is the UML representation of the generic case, MDI (Multiple Document Interface) or Multiple Master Interface (MMI) in case of Web-Applications:-

So that’s it for now, I hope you have enjoyed this MMI journey with me, although the flight was a little bit bumpy, but we are happy that we are safely landed back to home (page). Now enjoy the framework, all you need is to include assembly Shams.Web.UI.MasterPages.dll and start using it. I have also included an example that will help you in designing your applications. Please send me your feedbacks for further improvement of the framework, thanks.

Conclusion

Software architecture revolves around structure, and framework provides the structure to it. The framework is the foundation for any application being developed. Poor foundation leads to poor applications that require more maintenance cost and would be very inefficient by nature. So whenever you decide for a framework development, look for some one who is a domain expert for the particular business and have lots of design experience as well, in that way, you would be able to develop something that is reusable and extensible in nature.