Chapter 23: Designing Rich Internet Applications
For more details of the topics covered in this guide, see Contents of the Guide.
- General Design Considerations
- Specific Design Issues
- Security Considerations
- Data Handling Considerations
- Technology Considerations
- Deployment Considerations
- Relevant Design Patterns
- Additional Resources
In this chapter, you will learn about the key scenarios for Rich Internet Applications (RIAs), understand the components found in a RIA, and learn about the key design considerations for RIAs. This includes the guidelines for performance, security, and deployment; in addition to key patterns and technology considerations for designing RIAs.
Architecture of a typical RIA implementation. Broken lines indicate optional components.
A typical Rich Internet Application is decomposed into three layers: the presentation layer, business layer, and data layer. The presentation layer usually contains UI and presentation logic components; the business layer usually contains business logic, business workflow and business entities components; the data layer usually contains data access and service agent components.
It is common in RIAs to move some of business processing and even the data access code to the client. Therefore, the client may in fact contain some or all of the functionality of the business and data layers, depending on the application scenario. Figure 1 shows how some business processing is usually implemented on the client.
RIAs can range from thin interfaces that overlay back end business services, to complex applications that perform most of the processes themselves and only communicate with back end services to consume or send back information. Therefore, the design and implementation varies. However, in terms of the presentation layer and the way that it communicates with back end services, there are some common approaches to good architectural design. Most of these are based on well-known design patterns that encourage the use of separate components within the application to reduce dependencies, make maintenance and testing easier, and promote reusability.
For more information about layered design, see Chapter 5, "Layered Application Guidelines." For more information about the components appropriate for each layer, see Chapter 10 "Component Guidelines."
General Design Considerations
The following guidelines provide information about several aspects you should consider when designing a RIA, and will help to ensure that your application meets your requirements and performs efficiently in scenarios common to RIAs:
- Choose a RIA based on audience, rich interface, and ease of deployment. Consider designing a RIA when your vital audience is using a browser that supports RIAs. If part of your vital audience is on a non-RIA supported browser, consider whether limiting browser choice to a supported version is a possibility. If you cannot influence the browser choice, consider if the loss of audience is significant enough to require choice of an alternative type of application, such as a Web application using AJAX. With a RIA, the ease of deployment and maintenance is similar to that of a Web application, assuming that your clients have a reliable network connection. RIA implementations are well suited to Web-based scenarios where you need visualization beyond that provided by basic HTML. They are likely to have more consistent behavior and require less testing across the range of supported browsers when compared to Web applications that utilize advanced functions and code customizations. RIA implementations are also perfect for streaming-media applications. They are less suited to extremely complex multipage UIs.
- Design to use a Web infrastructure utilizing services. RIA implementations require an infrastructure similar to Web applications. Typically, a RIA will perform processing on the client, but also communicate with other networked services; for example, to persist data in a database.
- Design to take advantage of client processing power. RIAs run on the client computer and can take advantage of all the processing power available there. Consider moving as much functionality as possible onto the client to improve user experience. Sensitive business rules should still be executed on the server, because the client logic can be circumvented.
- Design for execution within the browser sandbox. RIA implementations have higher security by default and therefore may not have access to all resources on a machine, such as cameras and hardware video acceleration. Access to the local file system is limited. Local storage is available, but there is a maximum limit.
- Determine the complexity of your UI requirements. Consider the complexity of your UI. RIA implementations work best when using a single screen for all operations. They can be extended to multiple screens, but this requires extra code and screen flow consideration. Users should be able to easily navigate or pause, and return to the appropriate point in a screen flow, without restarting the whole process. For multi-page UIs, use deep linking methods. Also, manipulate the Uniform Resource Locator (URL), the history list, and the browser's back and forward buttons to avoid confusion as users navigate between screens.
- Use scenarios to increase application performance or responsiveness. List and examine the common application scenarios to decide how to divide and load components of your application, as well as how to cache data or move business logic to the client. To reduce the download and startup time for the application, segregate functionality into separate downloadable components.
- Design for scenarios where the plug-in is not installed. Because RIA implementations require a browser plug-in, you should design for non-interruptive plug-in installation. Consider whether your clients have access to, have permission to, and will want to install the plug-in. Consider what control you have over the installation process. Plan for the scenario where users cannot install the plug-in by displaying an informative error message, or by providing an alternative Web UI.
In addition to the guidelines above that are especially applicable to RIA implementations, consider the more general guidelines for rich client applications in general (including mobile rich clients). These guidelines include separating presentation logic from interface implementation, identifying presentation tasks and presentation flows, separating business rules and other tasks not related to the interface, reusing common presentation logic, loosely coupling your client to any remote services it uses, avoiding tight coupling to objects in other layers, and reducing round trips when accessing remote layers. For more information, see Chapter 22 "Designing Rich Client Applications."
Specific Design Issues
There are several common issues that you must consider as your develop your design. These issues can be categorized into specific areas of the design. The following sections contain guidelines to help you resolve the common issues in each area:
- Business Layer
- Data Access
- Exception Management
- Media and Graphics
- State Management
In most scenarios, RIAs will access data or information located outside the application. While the nature of the information will vary, it is likely to be extracted from a business system. To maximize performance and usability, you might consider locating some of the business processing tasks on the client. Consider the following guidelines when designing interaction with business and service layers:
- Identify the business layers and service interfaces that the application will use. The business layer on the client should access the service interfaces using a service agent. Service agents can typically be implemented by generating a service proxy using the service definition.
- If your business logic does not contain sensitive information, consider locating some of the business rules on the client to improve performance and responsiveness of the application. If your business logic does contain sensitive information, you should locate it on the application server.
- Consider how the client will obtain information required to operate business rules and other client-side processing, and how it will update the business rules automatically as requirements change. You might want to have the client obtain business rule information from the business layer when it starts up.
- If your RIA implementation allows creation of an instance without a UI, consider using it to implement business processes using more structured, powerful, or familiar programming languages (such as C#) instead of using less flexible browser-supported languages.
- If your business logic is duplicated on the client and the server, use the same code language on the client and server if your RIA implementation allows it. This will reduce any differences in language implementations and make it easier to be consistent in how rules are processed. Domain models that can exist on both the server and client side should be as similar as possible.
- For security reasons, do not put sensitive unencrypted business logic on the client. The code in downloaded XAP files can easily be decompiled. Implement sensitive business logic on the server and access it using Web services.
For more information about implementing the business layer, see Chapter 7 "Business Layer Guidelines."
RIA implementations generally use the normal browser caching mechanism. Caching resources intelligently will improve application performance. Consider the following guidelines when designing a caching strategy:
- By dividing large client applications into smaller separately downloadable components, you can cache these components to improve performance and minimize network round trips. Avoid downloading and instantiating the entire application at start up if possible. Use installation, updates, and user scenarios to derive ways to divide and load application modules. For example, load stubs at start up and then dynamically load additional functionality in the background. Consider using events to intelligently preload modules just before they may be required.
- Allow the browser to cache objects that are not likely to change during a session. Utilize specific RIA local storage for information that changes during a session, or which should persist between sessions.
- To avoid unintended exceptions, check that isolated storage is large enough to contain the data you will write to it. Storage space does not increase automatically; you must ask the user to increase it.
For more information about designing a caching strategy, see Chapter 17 "Crosscutting Concerns."
RIA implementations should use the asynchronous call model for services to avoid blocking browser processes. Cross domain, protocol, and service efficiency issues should be considered as part of your design. If your RIA implementation allows it, consider using a different thread for background operations. Consider the following guidelines when designing a communication strategy:
- If you have long-running operations, consider using a background thread or asynchronous execution to avoid blocking the UI thread.
- Ensure that the RIA and the services it calls use compatible bindings that include security information. If you are authenticating through services, design your services to use a binding that your RIA implementation supports.
- To protect sensitive information and communication channels, consider using Internet Protocol Security (IPSec) and Secure Sockets Layer (SSL) to secure the channel, encryption to protect data, and digital signatures to detect data tampering.
- If your RIA client must access a server other than the one from which it was downloaded, ensure that you use a cross-domain configuration mechanism to permit access to the other servers/domains.
- Consider using a duplex mechanism with Windows Communication Foundation (WCF) to push data to the client if client polling causes heavy server load, or to push information to the server when this is significantly more efficient than using services; for example, real time multiplayer gaming scenarios utilizing a central server. However, be aware that firewalls and routers may block some ports and protocols. See "Additional Resources" at the end of this chapter for more information.
For more information about designing services, see Chapter 25 "Designing Service Applications." For more information about communication protocols and techniques, see Chapter 18 "Communication and Messaging."
Composition lets you build applications that can be maintained or extended more easily without reimplementation or redeployment of the entire application. You can implement your application from a number of modules, and have the components within those modules be loosely coupled. This can allow the application to be extended by deploying a new module or a new version of a module; or allow the application to be more easily customized or personalized by the user, or tailored to the user's role or task. Consider the following guidelines when designing a composition strategy:
- Evaluate whether composition is appropriate for your scenario; and, if so, which composition model patterns are most suitable. Composition can help you to design applications that can be reused in different scenarios with minimal or no changes. However, avoid designs that introduce dependencies that will require frequent application redeployment.
- Composition is well suited to mash-up applications that integrate information and functionality from disparate sources, or in situations where the application user extensible or customizable.
RIA implementations request data from the Web server through services in the same way as an AJAX client. After data reaches the client, it can be cached to maximize performance. Consider the following guidelines when designing a data-access strategy:
- Use client-side caching to minimize the number of round trips to the server, and to provide a more responsive UI.
- Filter data at the server rather than at the client to reduce the amount of data that must be sent over the network.
For more information about designing a data layer, see Chapter 8 "Data Layer Guidelines."
A robust and well designed exception management strategy can simplify application design, and improve security and manageability. It can also make it easier for developers to create the application, and reduces development time and cost. In a RIA, you will usually need to notify the user when an error occurs. In addition, for anything other than trivial UI errors such as validation messages, you should consider logging errors and exceptions on the server for use by operations staff and monitoring systems. You must also consider managing asynchronous exceptions, as well as exception coordination between the client and server code. Consider the following guidelines when designing an exception management mechanism:
- Design for both synchronous and asynchronous exceptions. Use try/catch blocks to trap exceptions in synchronous code. Put exception handling for asynchronous service calls in a separate handler designed specifically for such exceptions; for example, in Silverlight, this is the OnError handler.
- Design an approach for catching and handling unhandled exceptions. Unhandled exceptions in RIAs are passed to the browser. They will allow execution to continue after the user dismisses a browser error message. Provide a friendly error message for the user if possible. Stop program execution if continued execution would be harmful to the data integrity of the application or could mislead the user into thinking the application is still in a stable state.
- Only catch internal exceptions that you can handle. For example, catch data conversion exceptions that can occur when trying to convert null values. Do not use exceptions to control business logic
- Design an appropriate exception propagation strategy. For example, allow exceptions to bubble up to boundary layers where they can be logged and transformed as necessary before passing them to the next layer.
- Design an appropriate logging and notification strategy for critical errors and exceptions that does not reveal sensitive information.
For more information about designing an exception management strategy, see Chapter 17 "Crosscutting Concerns."
Logging for the purpose of debugging or auditing can be challenging in a RIA implementation. For example, access to the client file system is not available in Silverlight applications, and execution of the client and the server proceed asynchronously. Log files from a client user must be combined with server log files to gain a full picture of program execution. Consider the following guidelines when designing a logging strategy:
- Consider the limitations of the logging component in the RIA implementation. Some RIA implementations log each user's information in a separate file, perhaps in different locations on the disk.
- Determine a strategy to transfer client logs to the server for processing. Recombination of different users' logs from the same machine may be necessary if troubleshooting a client machine—specific issue. Avoid segregating logs by machine instead of by user, as there could be several users for each client machine.
- If using isolated storage for logging, consider the maximum size limit and the need to ask the user to increase storage capacity when required.
- Ensure that you log critical errors, and consider enabling logging and transferring logs to the server when exceptions are encountered.
Media and Graphics
RIA implementations provide a much richer experience and better performance than ordinary Web applications. Research and utilize the built-in media capabilities of your RIA platform. Keep in mind the features that may not be available on the RIA platform compared to a stand-alone media player. Consider the following guidelines when designing for multimedia and graphics:
- Design to utilize streaming media and video in the browser instead of invoking a separate player utility. In general, you should always use adaptive streaming in conjunction with RIA clients to gracefully and seamlessly handle varying bandwidth issues.
- To increase performance, position media objects on whole pixels and present them in their native size, and utilize the native vector graphics engine for the best drawing performance.
- If programming an extremely graphics-intensive application, investigate if your RIA implementation provides hardware acceleration. If it does not, create a baseline for what is acceptable drawing performance. Consider a plan to reduce load on the graphics engine if it falls below acceptable limits.
- Be aware of the size of your drawing areas. Only redraw parts of an area that are actually changing. Reduce overlapping regions when not necessary to reduce blending. Use profiling and debugging methods—for example, the “EnableRedrawRegions = true” setting in Silverlight—to discover which areas are being redrawn. Note that certain effects, such as blurring, can cause every pixel in an area to be redrawn. Windowless and transparent controls can also cause unintended redrawing and blending.
RIA implementations provide a much richer experience than an ordinary mobile application. Utilize the built-in media capabilities of the RIA platform you are using. Consider the following guidelines when designing for mobile device multimedia and graphics:
- When a RIA must be distributed to a mobile client, research whether a RIA plug-in implementation is available for the device you want to support. Find out if the RIA plug-in has reduced functionality compared to non-mobile platforms.
- Attempt to use a single or similar codebase. Then, if required, branch code for specific devices.
- Ensure that your UI layout and implementation is suitable for the smaller screen size of mobile devices. RIAs work on mobile devices, but consider using different layout code on each type of device to reduce the impact of different screen sizes when designing for Windows Mobile.
For more information about implementing a mobile application, see Chapter 24 "Designing Mobile Applications."
One of the main benefits of RIAs is the portability of compiled code between different browsers, operating systems, and platforms. Similarly, using a single source codebase, or similar codebases, reduces the time and cost of development and maintenance while still providing platform flexibility. Consider the following guidelines when designing for portability:
- Make full use of the native RIA code libraries and design for the goal of “write once, run everywhere,” but be willing to fork code in cases where overall project complexity or feature tradeoffs dictate that you must do so.
- If your audience will be running the RIA on multiple platforms, do not use features available only on one platform; for example, Windows Integrated Authentication. Design a solution based on portable RIA routines and features that are available in a range of clients.
- If you are targeting rich client and RIA applications, consider languages and development environments such as the patterns & practices Composite Client Application Guidance that can target both platforms. For more information, see "Composite Client Application Guidance" at http://msdn.microsoft.com/en-us/library/cc707819.aspx.
Because RIA applications are normally constrained to the browser, they tend to work best when designed as one central interface. Applications with multiple pages require that you consider how you will link between pages. Consider the following guidelines when designing for presentation:
- Use Separated Presentation patterns to separate the visual representation of your application from the presentation logic of your application.
- Take advantage of data binding capabilities to display data whenever possible, especially for tabular and multirow data presentation. This reduces the code required, simplifies development, and reduces coding errors. It can also automatically synchronize data in different views or forms. Use two-way binding where the user must be able to update the data.
- For multipage UIs, use deep-linking methods to allow unique identification of and navigation to individual application pages.
- Trap the browser forward and back button events to avoid unintentional navigation away from your page. Also, consider the ability to manipulate the browser's address text box content, and history list in order to implement normal Web page-like navigation.
For more information about implementing presentation layers, see Chapter 6 "Presentation Layer Guidelines."
You can store application state on the client using isolated storage, which is useful for maintaining or caching state locally between user sessions. Isolated storage is not managed in the same way as the browser cache. Applications that write data to isolated storage must either delete it directly, or explicitly instruct the user to remove the data. Consider the following guidelines when designing for state management:
- Determine the state information that the application must store, including estimates of the size, the frequency of changes, and the processing or overhead cost of re-creating or refetching the data.
- Store state on the client in isolated storage to persist it during and between sessions. State that is required for the application to function should always be stored on the server. This also allows users to access saved state when logging on from a different computer.
- Design for multiple concurrent sessions because you cannot prevent multiple RIA instances from initializing. Design either for concurrency in your state management, or to detect and prevent multiple sessions from corrupting application state.
Validation must be performed using code on the client or through services located on the server. If you require more than trivial validation on the client, isolate validation logic in a separate downloadable assembly. This makes the rules easy to maintain. Consider the following guidelines when designing for validation:
- Use client-side validation to maximize the user experience, but always use server-side validation as well for security. In general, assume that all client-controlled data is malicious. The server should revalidate all data sent to it. Design to validate input from all sources, such as the query string, cookies, and HTML controls.
- Design your validation mechanisms to constrain, reject, and sanitize data. Validate input for length, range, format, and type. Identify trust boundaries on the server and validate data that passes across them.
- Consider using isolated storage to hold client-specific validation rules. For rules that require access to server resources, evaluate whether it is more efficient to use a single service call that performs validation on the server.
- If you have a large volume of client-side validation code that may change, consider locating it in a separate downloadable module so it can be easily replaced without downloading the entire RIA application again.
For more information about validation techniques, see Chapter 17 "Crosscutting Concerns."
Security encompasses a range of factors and is vital in all types of applications. Rich Internet applications must be designed and implemented with security in mind, and—where they act as the presentation layer for business applications—must play their part in protecting and securing the other layers of the application. Security issues involve a range of concerns, including protecting sensitive data, user authentication and authorization, guarding against attack from malicious code and users, and auditing and logging events and user activity.
Consider the following guidelines when designing a security strategy:
- Determine the appropriate technology and approach for authenticating users. You should consider how and when to log on users, whether you need to support different types of users (different roles) with differing permissions (such as administrators and standard users), and how you will record successful and failed logons.
- Consider using Windows Integrated Authentication, a single sign-on (SSO) mechanism, or a federated authentication solution if users must be able to access multiple applications with the same credentials or identity. If you cannot use Windows Integrated Authentication, you may be able to use an external agency that offers federated authentication support. If you cannot use an external agency, consider using a certificate-based system, or create a custom solution for your organization.
- Consider the need to validate inputs, both from the user and from sources such as services and other application interfaces. You might need to create custom validation mechanisms, or you might be able to take advantage of the validation features of the UI Technology you are working with.
- Consider how you will implement auditing and logging for the application, and what information to include in these logs. Remember to protect sensitive information in the logs using encryption, and optionally use digital signatures for the most sensitive information that is vulnerable to tampering.
Data Handling Considerations
Application data is typically accessed through networked services. Cache this data on the client to improve performance and enable offline usage. Application data falls typically into two categories:
- Read-only reference data. This is data that does not change often and is used by the client for reference purposes, such as a product catalog. Store reference data on the client to reduce the amount of data interchange between the client and the server in order to improve the performance of your application, enable offline capabilities, provide early data validation, and generally improve the usability of your application.
- Transient data. This is data that can be changed on the client as well as on the server. One of the most challenging aspects of dealing with transient data in rich Internet applications is dealing with concurrency issues where the same data can be modified by multiple clients at the same time. You must keep track of any client-side changes made to transient data on the client and manage updates on the server that may contain conflicting changes.
The following guidelines discuss Silverlight and Microsoft Windows Communication Foundation (WCF) and provide specific guidance for these technologies. At the time of writing, the latest versions are WCF 3.5 and Silverlight 3.0. Use the guidelines to help you to choose and implement an appropriate technology.
Versions and Target Platforms
- At the time of the release of this guide, Silverlight for Mobile was an announced product and in development, but not released.
- Silverlight currently supports the Safari, Firefox, and Microsoft Internet Explorer browsers using a plug-in. Through these browsers, Silverlight currently supports Mac and Windows. Support for Windows Mobile was also announced in 2008. An open source implementation of Silverlight, called Moonlight, provides support for Linux and Unix/X11 systems.
- Silverlight supports the C#, Iron Python, Iron Ruby, and Visual Basic® .NET development languages. Most XAML code will also run in both WPF and Silverlight hosts.
- In Silverlight 2.0, you must implement custom code for input and data validation. Silverlight 3.0 provides support for exception-based data validation through data binding. Check the documentation to verify if this is true for later versions.
- The .NET cryptography APIs are available in Silverlight and should be utilized when storing sensitive data and communicating it to the server if it is not already encrypted using another mechanism.
- Silverlight logs to an individual file in the user store for a specific logged in user. It cannot log to one file for the whole machine.
- Silverlight does not obfuscate downloaded modules, which can be decompiled and the programming logic extracted.
- Silverlight supports only asynchronous calls to Web services.
- Silverlight supports only Basic HTTP binding. WCF in .NET 3.5 supports Basic HTTP binding, but security is not turned on by default. Be sure to turn on at least transport security to secure your service communications.
- Silverlight supports two file formats to deal with calling services in a different domain to the source of the current page. You can use either a ClientAccessPolicy.xml file specific to Silverlight, or a CrossDomain.xml file compatible with Adobe Flash. Place the file in the root of the server(s) to which your Silverlight client needs access.
- Consider using ADO.NET Data Services in a Silverlight application if you must transfer large volumes of data from the server.
- Silverlight does not currently support SOAP faults exposed by services due to the browser security model. Services must return exceptions to the client through a different mechanism.
- Silverlight contains controls specifically designed for it. Third parties are likely to have additional control packages available.
- Use Silverlight windowless controls if you want to overlay viewable HTML content and controls on top of a Silverlight application.
- Silverlight allows you to attach additional behaviors to existing control implementations. Use this approach instead of attempting to subclass a control.
- Silverlight performs antialiasing for all UI components, so consider the recommendations regarding snapping UI elements to whole pixels.
- The local storage mechanism for Silverlight is the client machine's Isolated Storage cache. The initial maximum size is 1 megabyte (MB). The maximum storage size is unlimited; however, Silverlight requires that your application request the user to increase the storage size.
See also "Contrasting Silverlight and WPF" at http://msdn.microsoft.com/en-us/library/dd458872.aspx.
RIA implementations provide many of the same benefits as Web applications in terms of deployment and maintainability. Design your RIA as separate modules that can be downloaded individually and cached to allow replacement of one module instead of the whole application. Version your application and components so that you can detect the versions that clients are running. Consider the following guidelines when designing for deployment and maintainability:
- Consider how you will manage the scenario where the RIA browser plug-in is not installed.
- Consider how you will redeploy modules when the application instance is still running on a client.
- Divide the application into logical modules that can be cached separately, and that can be replaced easily without requiring the user to download the entire application again.
- Version your components.
Installation of the RIA Plug-In
Consider how you will manage installation of the RIA browser plug-in when it is not already installed:
- Intranet. If available, use application distribution software or the Group Policy feature of the Microsoft Active Directory® directory service to preinstall the plug-in on each computer in the organization. Alternatively, consider using Windows Update, where Silverlight is an optional component. Finally, consider manual installation through the browser, which requires the user to have Administrator privileges on the client machine.
- Internet. Users must install the plug-in manually, so you should provide a link to the appropriate location to download the latest plug in. For Windows users, Windows Update provides the plug-in as an optional component.
- Plug-in updates. In general, updates to the plug-in take into account backward compatibility. You may target a particular plug-in version, but consider implementing a plan to verify your application's functionality on new versions of the browser plug-in as they become available. For intranet scenarios, distribute a new plug-in after testing your application. In Internet scenarios, assume that automatic plug-in updates will occur. Test your application using the plug-in beta to ensure a smooth user transition when the plug-in is released.
Because RIA implementations copy or move presentation logic to the client, a distributed architecture is the most likely scenario for deployment. In a distributed RIA deployment, the presentation logic is on the client; the business layer can be on the client, on the server, or shared across the client and server; and the data layer resides on the Web server or application server. Typically, you will move some of your business logic (and even, perhaps, some of the data access logic) to the client to maximize performance. In this case, your business and data access layers will tend to extend across the client and the application server, as shown in Figure 2.
Distributed deployment for a RIA
Consider the following guidelines for deploying a RIA:
- If your applications are large, factor in the processing requirements for downloading the RIA components to clients.
- If your business logic is shared by other applications, consider exposing it as a service on the server so that all applications can access it.
- If you use sockets or WCF in your application and you are not using port 80, consider how firewalls that commonly block other ports will affect your application.
- Ensure that you use a crossdomain.xml file so that RIA clients can access other domains when required.
When you deploy your application on multiple servers, you can use load balancing to distribute RIA client requests to different servers. This improves response times, increases resource utilization, and maximizes throughput. Figure 3 shows a load-balanced scenario.
Load balancing a RIA deployment
Consider the following guidelines when designing your application to use load balancing:
- Avoid server affinity. Server affinity occurs when all requests from a particular client must be handled by the same server. It is most often introduced by using locally updatable caches or in-process or local session state stores.
- Consider storing all state on the client and designing stateless business components.
- Consider using network load balancing software to implement redirection of requests to the servers in an application farm.
Web Farm Considerations
If your RIA application has significant business logic, data access or data processing requirements on the application server, consider using a Web farm that distributes requests from RIA clients to multiple servers. A Web farm allows you to scale out your application, and reduces the impact of hardware failures. You can use either load balancing or clustering solutions to add more servers for your application. Consider the following guidelines:
- Consider using clustering to reduce the impact of hardware failures, and partitioning your database across multiple database servers if your application has high I/O requirements.
- If you must support server affinity, user-specific cached data or state, configure the Web farm to route all requests for the same user to the same server.
- Do not use in-process session management in a Web farm unless you implement server affinity, because requests from the same user cannot be guaranteed to be routed to the same server otherwise. Use the out-of-process session service or a database server for this scenario.
For more information on deployment patterns and scenarios, see Chapter 19 "Physical Tiers and Deployment."
Relevant Design Patterns
Key patterns are organized into categories such as Layers, Communication, Composition, and Presentation; as shown in the following table. Consider using these patterns when making design decisions for each category.
Service Layer. An architectural design pattern where the service interface and implementation is grouped into a single layer.
Asynchronous Callback. Execute long-running tasks on a separate thread that executes in the background, and provide a function for the thread to call back into when the task is complete.
Command. Encapsulate request processing in a separate command object that exposes a common execution interface.
Composite View. Combine individual views into a composite view.
Inversion of Control. Populate any dependencies of objects on other objects or components that must be fulfilled before the object can be used by the application.
Application Controller. An object that contains all of the flow logic and is used by other Controllers that work with a Model and display the appropriate View.
Supervising Presenter. Separate presentation design into three separate roles, with the View being responsible for handling user input and being data bound against a Model component that encapsulate business data. A Presenter object implements presentation logic and coordinates interactions between the View and Model.
Presentation Model. A variation of Model-View-Presenter (MVP) pattern that is tailored for modern UI development platforms where the View is the responsibility of a designer rather than a developer.
For more information on the Composite View pattern, see "Patterns in the Composite Application Library" at http://msdn.microsoft.com/en-us/library/dd458924.aspx.
For more information on the Model-View-Controller (MVC) and Application Controller patterns, see Fowler, Martin. Patterns of Enterprise Application Architecture. Addison-Wesley, 2002. Or at http://martinfowler.com/eaaCatalog/.
For more information on the Command pattern, see Chapter 5, "Behavioral Patterns" in Gamma, Erich, Richard Helm, Ralph Johnson, and John Vlissides. Design Patterns: Elements of Reusable Object-Oriented Software. Addison Wesley Professional, 1995.
For more information on the Asynchronous Callback pattern, see "Creating a Simplified Asynchronous Call Pattern for Windows Forms Applications" at http://msdn.microsoft.com/en-us/library/ms996483.aspx.
For more information on the Service Layer pattern, see "P of EAA: Service Layer" at http://www.martinfowler.com/eaaCatalog/serviceLayer.html.
For more information, see the following resources:
- For information on Silverlight, see the official Silverlight Web site at http://silverlight.net/.
- For information on using WCF with Silverlight, see "How to: Build a Duplex Service" at http://msdn.microsoft.com/en-us/library/cc645027(VS.95).aspx and "How to: Access a Duplex Service with the Channel Model" at http://msdn.microsoft.com/en-us/library/cc645028(VS.95).aspx.
- For Silverlight blogs, see Brad Abrams's blog at http://blogs.msdn.com/brada/ and Scott Guthrie's blog at http://weblogs.asp.net/Scottgu/.