Export (0) Print
Expand All
1 out of 1 rated this helpful - Rate this topic

Design Review for Application Blocks

Retired Content

This content is outdated and is no longer being maintained. It is provided as a courtesy for individuals who are still using these technologies. This page may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist.

 

patterns & practices Developer Center

Microsoft Corporation

January 2005

Summary: Describes how to perform design reviews for an application block for functional, deployment, performance, scalability, security, and globalization considerations.

Contents

Objectives

Overview

Design Review Process

Tools for Architecture and Design Review

Summary

Objectives

  • Learn the process for design review of a .NET application block.

Overview

The key to an efficient application block is a design based on sound principles. The goal of the design review is to ensure that the design for the .NET application block addresses all of the requirements and deployment scenarios. The reviewers should make sure that the design makes appropriate tradeoffs based on best practices and established principles for performance, scalability, security, maintainability, and so on. Design review is very important to the overall productivity of the project because it allows you to discover design errors early, rather than during development or testing, which can result in significant rework, as well as cost and schedule overruns.

This chapter describes the design review process for a .NET application block. To provide design review examples, this chapter refers to the Configuration Management Application Block (CMAB). The requirements for the CMAB are as follows:

  • Must read and store configuration information transparently in a persistent storage medium. The storage media are Microsoft® SQL Server™, the registry, and XML files.
  • Must provide a configurable option to store the information in encrypted form and in plain text by using XML notation.
  • Can be used with desktop applications as well as Web applications that are deployed in a Web farm.
  • Must cache configuration information in memory to reduce cross-process communication, such as reading from any persistent medium. This reduces the response time of the request for any configuration information. The expiration and scavenging mechanism for cached-in-memory data is similar to the cron algorithm in UNIX.
  • Can store and return data from various cultures/locales without any loss of data integrity.

Design Review Process

The process for the design review of application blocks is outlined below.

Input

The following input is required for the design review:

  • Application requirements
  • Performance model
  • Design-related documents (for example, architecture diagrams, class interaction diagrams, and so on)
  • Deployment scenarios
  • Security policy document

Steps

The design review consists of the following steps:

  1. Create test plans.
  2. Verify that the design addresses all functional specifications and requirements.
  3. Verify that the design addresses all deployment scenarios.
  4. Verify that the design considers the performance and scalability tradeoffs and best practices.
  5. Verify that the design considers the security tradeoffs and best practices.
  6. Verify that the design employs best practices and principles for ease of maintenance and customization.
  7. Verify that the design addresses globalization issues for the specified cultures.
  8. Verify that the design has an effective exception management strategy.

The following sections cover each step in detail.

Step 1: Create Test Plans

As a first step, create detailed test plans (DTP) and detailed test cases (DTC) for the design review. When you create these plans, use various perspectives, such as performance, security, exception management, and so on.

Table 4.1 shows some of the test cases that were used in the design review perspective for the CMAB. These test cases are based on the first iteration of test planning. As your design progresses, you may have test cases created to evaluate several prototypes.

Table 4.1: Test Cases from DTP Document for CMAB Design Review

Scenario 1Conduct design review of the CMAB
PriorityHigh
Comments 
1.1HighVerify that the design addresses all of the requirements of the CMAB.
1.2HighVerify that the design address all of the deployment scenarios for the CMAB.
1.3HighVerify that the design follows the best practices and considers the tradeoffs for better performance and scalability.
1.4HighVerify that the design follows security best practices.
1.5HighVerify that the design addresses the globalization requirements.
1.6MediumVerify that the design considers the globalization best practices.
1.7HighVerify that the design follows exception management best practices.
1.8HighVerify that the design follows maintainability and extensibility best practices.

More Information

For more information about how to create test plans for an application block, see Chapter 3, "Testing Process for Application Blocks."

Step 2: Verify That the Design Addresses All Functional Specifications and Requirements

The first important step in the design review process is to make sure that the design follows the functional specifications and meets all requirements. This is critical to the later stages of development because missing functionality can seriously restrict the usefulness of the application block.

It is helpful if the requirements and functional specification documents are translated into checklists. The reviewers can then work through these checklists to ensure that each specified function and requirement is translated into a design feature for the application block. A sample checklist for CMAB is shown in Table 4.2.

Table 4.2: Sample Checklist for CMAB

Functional requirement
Implemented?

Feature that implements requirement
The CMAB must provide a standard interface for reading and writing application configuration data. The interface must be easy to use and independent of the underlying data store.YesCustom storage provider (CSP) that implements either the IConfigurationStorageWriter or the IConfigurationStorageReader interface.
The CMAB must allow programmers to work with configuration data using the most appropriate in-memory data structure.YesCustom section handler (CSH) that implements two interfaces: IConfigurationSectionHandler and IConfigurationSectionHandlerWriter.
The CMAB must be easily configurable using standard .NET configuration files.YesConfiguration Manager class

Configuration settings in the App.config/Web.config file: <applicationConfigurationManagement defaultSection="XXXXXX " >
.....
</applicationConfigurationManagement>
The CMAB must support the optional caching of application configuration data to improve performance. The use of caching must be controlled by configuration settings, independent of the underlying data store, and transparent to the application that is using the CMAB.YesCacheFactory class

Configuration settings in the App.config/Web.config file:
<configCache
enabled="true"
refresh="1 * * * *" />
The CMAB must support the optional encryption and decryption of application configuration data to improve data security. The use of encryption must be controlled by configuration settings, independent of the underlying data store, and transparent to the application that is using the CMAB.YesData protection provider (DPP) that implements the IDataProtection interface.

Configuration settings in the App.config/Web.config file:
<protection Provider assembly="..."
type="..."
hashKey="..."
symmetricKey="..."
initializationVector="..."/>
The CMAB must provide a set of static methods so that the user does not have to instantiate any objects before use.Yespublic static object Read (string sectionName ) {....}

public static void Write (string sectionName, object configValue) {......}
Most applications use a single (default) configuration section; therefore the CMAB should provide a simpler interface for interacting with the default configuration section.YesConfiguration settings in the App.config/Web.config file:

<applicationConfigurationManagement defaultSection="XXXXXX " >
........
</applicationConfigurationManagement>

public static void Write (Hashtable value ) {...}
public static HashTable Read () {.........}

Step 3: Verify That the Design Addresses All Deployment Scenarios

When reviewing the design for the application block, make note of the deployment scenarios in which the application block will be used. The design may assume certain features that are not available in all deployment situations. This could make the application block unusable for some of the deployment scenarios listed in the requirements.

For example, the CMAB can be deployed on a desktop as well as in a Web farm. You should ensure that the design does not use machine-specific encryption/decryption services, such as the Data Protection API, a service that is specific to the Microsoft Windows® 2000 operating system. The Data Protection API encrypts data by using machine-specific keys so that the data cannot be decrypted on other computers. For this reason, using this service could make the application block unsuitable for deployment in a Web farm. To correct this, the application block could use a machine-agnostic service, such as the System.Security.Cryptography namespace in the Microsoft .NET Framework Class Library.

As an alternative solution, the CMAB could provide multiple options for encrypting the data so that the user can choose the one that is most appropriate for his or her scenario. The encrypting option should be configurable in the configuration file for the application block.

Multiple deployment scenarios require that you make tradeoffs with respect to performance and security. If these tradeoffs are not determined in the design phase, then the application block may be too slow or may be a threat to the security of the network on which it is deployed. (These tradeoffs are validated more thoroughly in the Steps 4 and 5, where you will perform the performance and security design reviews.)

For example, with CMAB, you should carefully review the following deployment considerations:

  • CMAB caches the configuration data in memory. There may be scenarios where the available memory is reduced because of an increased amount of data cached in memory. This reduction in available memory may cause a performance bottleneck under high load situations on a Web farm or even on a desktop application that is required to have only a small working set. The design must address this possibility by providing an expiration mechanism that flushes the cache if the memory utilization crosses a particular threshold.
  • CMAB is required to write to SQL Server, which may be deployed on a separate computer. This may require the opening of SQL Server–specific TCP/IP ports in the internal firewall. Some networks may limit communication to HTTP port 80 on the internal firewall. If this is one of your deployment scenarios, the CMAB must have another abstraction layer installed on the computer running SQL Server so that it can capture information over port 80, and then store it in the database.

The deployment scenarios should be treated as deployment-related requirements. The documents that can help you to capture these scenarios are the functional requirements document, deployment topologies diagrams, documented deployment scenarios, and so on.

You must carefully review each deployment scenario, and then analyze its potential impact on the design. This review process ensures that any impact is reflected in the design model for the application block.

You may need to develop a simple code prototype at this stage, and then test it in a simulated deployment scenario to ensure that you have not overlooked any implications of a particular scenario.

More Information

Step 4: Verify That the Design Considers Performance and Scalability Tradeoffs and Best Practices

Performance and scalability should be considered early in the design phase of any product. It is very important that you review the design from this perspective, or the final product may consume more resources than allocated and may fail to meet performance objectives. In addition, the application block may not be able to handle the targeted work load. Performance objectives and resource utilization limits should be available in the requirements document or the performance model.

The performance and scalability review can be divided into the following steps. You may need to develop prototype code and then test the prototype in a simulated environment to validate the design assumptions.

  1. Verify that the design can meet the performance objectives using the allocated resources (CPU, memory, network I/O, and disk I/O).

    You may need to break a single usage scenario into smaller steps, and then allocate resources to these smaller steps. Validate the allocated budget by prototyping and testing it in a simulated environment.

    Note   This step is an important activity that is covered primarily in the performance modeling phase. If you do not plan to have an explicit performance modeling phase, you should still perform this exercise if you have any resource constraints.

    For more information about performance objectives and performance modeling, see Chapter 2, "Performance Modeling, " in Improving .NET Application Performance and Scalability on MSDN at http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnpag/html/scalenetchapt02.asp.

    For more information about how to conduct performance testing, see Chapter 16, "Testing .NET Application Performance," in Improving .NET Application Performance and Scalability on MSDN at http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnpag/html/scalenetchapt16.asp.

  2. Verify that the design addresses performance tradeoffs for various deployment scenarios. For example, CMAB caches configuration data in physical memory. Available memory on the computer can be reduced because of the amount of data cached in memory. This reduction in available memory may cause a performance bottleneck under high load scenarios on a Web farm. The design must address this issue by providing an expiration mechanism that flushes the cache if memory utilization crosses a particular threshold value.

    For more information about performance-related deployment considerations, see Chapter 3, "Design Guidelines for Application Performance," in Improving .NET Application Performance and Scalability on MSDN at http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnpag/html/scalenetchapt03.asp.

    For more information about the performance-related design tradeoffs and deployment considerations, see Chapter 4, "Architecture and Design Review of a .NET Application for Performance and Scalability," in Improving .NET Application Performance and Scalability on MSDN at http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnpag/html/scalenetchapt04.asp.

  3. Verify that the design follows principles and best practices for performance and scalability. As mentioned previously, performance and scalability best practices focus on using technology-agnostic principles in your design. Some important design principles are as follows:
    • Minimize transitions across boundaries.

      Try to keep transitions across boundaries to a minimum. Boundaries include application domains, apartments, processes, and computers. Each time a block must cross a boundary, it incurs costs in terms of security, serialization of data, additional latency involved in crossing the boundary, and so on.

    • Use early binding where possible.

      Application blocks that use late binding may be flexible, but late binding can affect performance because of the overhead involved in dynamically identifying and loading assemblies at run time. Most scenarios that use late binding provide configurable settings in a file.

    • Pool shared or scarce resources.

      Resources that are limited in number and are essential to optimized functioning of the application block must be treated as shared resources, and no single piece of code should hold on to them for a long time. Resources, such as database connections, threads, and so on, fall under this category. Review the application block design to locate places where thread creation can be replaced by allocating the parallel tasks to the CLR thread pool.

      For example, consider that the GetAltitudeData and GetVelocityData methods must be executed in parallel:

      public void GetFlightData(){
          GetAltitudeData(); //Executed in the current thread
      Thread seperateThread = new Thread(new ThreadStart(GetVelocityData));
          seperateThread.Start();
      }
        

      Rather than allocating a thread from the process thread pool, theGetAltitudeData method creates a new thread. This parallel execution of tasks defeats the concept of sharing resources.

      The following code shows how to use shared threads in the thread pool. Here the new thread is allocated from the thread pool; therefore, thread management is optimized and is taken care of by the .NET Framework.

      public void GetFlightData(){
      GetAltitudeData(); //Executed in the current thread
      ThreadPool.QueueUserWorkltem(new WaitCallBack(GetVelocityData));
      }
        
    • Partition functionality into logical layers.

      Keep the methods that perform similar functions or act on the same data in the same class. Classes that are similar in functionality should be in the same assembly. In this way, closely related classes and data are located near each other, which reduces boundary transitions. Grouping data logically increases both performance and maintainability.

    • Reduce contention by minimizing lock times.

      Review the transactions and the granularity of the locks used in the application block. Lock times can introduce resource contention, and, as a result, the application block may not be able to meet performance objectives.

      For more information about performance-related design guidelines, see Chapter 3, "Design Guidelines for Application Performance," in Improving .NET Application Performance and Scalability on MSDN at http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnpag/html/scalenetchapt03.asp.

      For questions about architecture and design review for performance, see Chapter 4, "Architecture and Design Review of a .NET Application for Performance and Scalability," in Improving .NET Application Performance and Scalability on MSDN at http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnpag/html/scalenetchapt04.asp.

      For a checklist on architecture and design review of .NET applications from a performance perspective, see "Checklist: Architecture and Design Review for Performance and Scalability," in Improving .NET Application Performance and Scalability on MSDN at http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnpag/html/ScaleNetCheck02.asp.

  4. Verify that the design follows technology-specific best practices. The application block design should follow the best practices for .NET-related technologies. The design should instantiate .NET-specific design patterns for efficient resource cleanup, patterns for reducing the chattiness, and so on. For example, if the application block has a class that accesses an unmanaged COM component across multiple methods, the class must implement the Dispose pattern to allow the clients of the API to deterministically release unmanaged resources.

    If you develop a custom collection for value types and require frequent enumeration through the collection, you should implement the Enumerator pattern to reduce the overhead of virtual table lookup and boxing or unboxing.

    For more information about performance-related best practices, see the Part III, "Application Performance and Scalability," and the Checklists section of Improving .NET Application Performance and Scalability on MSDN at http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnpag/html/ScaleNet.asp,

  5. Verify that the design features do not compromise security for the sake of performance. During the design review process, you should identify the situations where the cost of security is significant and is hurting performance. However, make sure that you do not compromise security for the sake of performance. You should make a list of all such situations and carefully analyze them during the security review of the design. Analyzing these situations helps you make appropriate tradeoffs for performance and security.

    For example, if during prototype testing for the CMAB you find that frequent encryption and decryption causes excessive processor cycles, you can mitigate the performance impact by scaling up or out instead of eliminating data encryption. In other situations, you should do a threat analysis before lowering the security barrier.

More Information

For more information about performance-related best practices for .NET technologies, see Improving .NET Application Performance and Scalability, on MSDN at http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnpag/html/ScaleNet.asp.

Step 5: Verify That the Design Considers the Security Tradeoffs and Best Practices

Reviewing the application block design from the security perspective helps you to identify and understand security issues that may surface during later stages of the application block development life cycle. The cost and effort involved in fixing such issues increases as development progresses.

The design review should ensure the following:

  • Plugging the application block into an application does not introduce any security flaws in production.
  • The design evaluates the security tradeoffs and follows the best practices that lead to a secure design.

You should consider the following when you review the design:

  • Make sure that the application block design identifies the trust boundaries. Verify that the design identifies privileged code and uses sandboxing for the privileged code. (Sandboxing puts the privileged code in a separate assembly.)
  • Make sure that there is no dependency on a particular service or protocol that may not be available in a production environment.
  • Make sure that the application block has access to required resources so that it can provide the intended functionality. Ensure that all such resources can be made available in production scenarios without compromising security.
  • Make sure that the application block does not depend on special privileges or rights. The block should be designed to function with least privileges. If the application block is going to need special privileges, the design should evaluate and address the possible security tradeoffs.
  • Determine how the application block handles sensitive data. Does the block use cryptography? Does it follow best practices while doing so? Wherever possible, make sure that the design uses the classes available in the .NET Framework for cryptography.
  • Make sure that the design follows best practices for class design. For example, the design should restrict class and member visibility; the design should follow basic guidelines, such as sealing of non-base classes; and so on.

To ensure that the application block design is secure, consider the following best practices (as appropriate, depending on the functionality provided by the block):

  • Identify and review any areas that may be susceptible to SQL injections.

    If the application block is going to perform database access, make sure that the design ensures the correct use of data type, size, and format of the parameterized SQL queries (if used). Although stored procedures are used as risk mitigation for SQL injection attacks, they should be reviewed for any other possible security threats.

  • Review the areas where the application block accesses the file system or any other resources.

    Identify areas in the design where file access is required. Ensure that an authorization strategy is in place to access these resources.

  • Review the areas where sensitive data is used or passed.

    Review those portions of the design that pass, process, or store sensitive data such as user names, passwords, personal information, and so on. Look for the encryption strategy used.

  • Review exception management.

    Review the exception handling in the application block. Improper exception handling (unstructured) could lead to open connections or open files that are never closed, which could in turn lead to security attacks.

More Information

For an exhaustive list of all design review considerations and checklists, see Chapter 5, "Architecture and Design Review for Security," in Improving Web Application Security: Threats and Countermeasures on MSDN at http://msdn.microsoft.com/library/en-us/dnnetsec/html/THCMCh05.asp.

Step 6: Verify That the Design Uses Best Practices for Ease of Maintenance and Customization

Another area that is of critical importance to the users of an application block is the ease with which it can be customized and maintained after integration into an application. When completing your design review, consider the manageability of the code. Ensure that the design addresses the following best practices:

  • The design follows object-oriented principles so that the classes own the data on which they act.
  • The communication among various objects uses message-based communication instead of following the remote procedure call (RPC) model. Message-based communication requires that the communicating entities define and communicate by using a data contract. The use of a data contract ensures a high degree of encapsulation, thereby minimizing the impact that a change in one component can have on other components.
  • The data format for input parameters and return values is consistent.
  • The design follows a pattern-based approach for addressing various problems. A pattern-based approach ensures that, besides using a tried and tested solution to specific problems, developers can easily grasp the algorithm for a particular implementation.
  • The logic that enforces policies or provides complimentary features such as security, encryption, communication restriction, and so on, is abstracted as much as possible from the core functionality.

More Information

For more information, see the following resources:

Step 7: Verify That the Design Addresses Globalization Issues for the Desired Cultures

Globalization is the process of ensuring that a piece of software supports localized versions of user interface elements, such as messages, and can operate on regional data.

Before starting the design review, you know all of the cultures that the application block is required to support. The common issues related to globalization generally entail features such as string operations, formatting date and time in specific cultures, using calendars in specific cultures, comparing and sorting data in specific cultures, and so on.

Most of these issues can be addressed during the design process so that minimal changes are required to localize the application block for a particular region. When reviewing the application block design, verify the following:

  • All resources (error messages, informational messages, or any other nonexecutable data) that are used in the application block are stored in a resource file.
  • Any objects that need to be persisted in resource files are designed to be serializable.
  • If the application block has to be packaged with resources for different cultures, one resource file should be the default file and the other files should be contained in separate satellite assemblies. The default resource assembly is a part of main assembly.
  • Any classes that perform culture-specific operations should explicitly use the culture-aware APIs included in the .NET Framework. The classes should expose overloaded methods that accept culture-specific information. Review that the CultureInfo type and the IFormatProvider type are used to specify the culture in the overloaded methods for which the culture-specific operation must be performed.
  • The application block should primarily use Unicode encoding, although other types of encoding (such as double byte character sets [DBCS]) are also available. If you plan to use a database, such as SQL Server 2000, you should use Unicode-compatible data types for database design. For example, CMAB stores configuration information in a SQL Server database. This stored information can be from different character sets; therefore, you should review that the database design uses data types such as nchar, nvarchar, ntext, and so on.

More Information

Step 8: Verify That the Design Has An Effective Exception Management Strategy

An effective exception management strategy for an application block ensures that the block is capable of detecting exceptions, logging and reporting errors and warnings, and generating events that can be monitored externally.

When you review the application block design, verify that the design adheres to the following basic principles of effective exception management:

  • Instead of throwing generic exceptions, the application block should use specific classes for throwing specific types of exceptions. These exceptions should derive from the ApplicationException class. In this way, the clients of the application block can determine the appropriate action if an exception of a particular type occurs. For example, if the CMAB fails to read the configuration file during application initialization, it should throw an exception of type ConfigurationException or a class derived from ConfigurationException. The details of the error message can be written to the message property of the exception class.

    Consider the following code snippet in an application block that accesses a SQL data store.

    try{
        // Data access logic specific to the application block
    }
    catch (Exception e){
        //Perform some exception-related operation like logging or rollback
        //operations.
        throw e;
    }
      

    The preceding code snippet catches an exception and rethrows it to the calling code as an instance of the generic Exception class. This makes it difficult for the client to distinguish between types of exceptions and to have efficient application exception management logic in place. The preceding code snippet also introduces the redundant overhead of unnecessarily catching and rethrowing all of the exceptions without any value addition.

    The following code snippet shows how CMAB handles a similar scenario.

    try{
        // Data access logic specific to the application block
        rows = SqlHelper.ExecuteNonQuery( );
                
    }
    catch( Exception e)
    {
        throw new ConfigurationException( Resource.ResourceManager[ 
    "RES_ExceptionCantExecuteStoredProcedure",SetConfigSP, SectionName, paramValue, e ] );
        // log the exception in the event sink
    }
      

    CMAB catches the exception that occurs in the data access logic with SQL Server, and throws the exception as a ConfigurationException, which is an exception of a specific type. Moreover, the exception is logged in an event sink before it is sent to the client of the application block.

    You should review all sequence diagrams (if available) and determine the exceptional flows for each usage scenario. Also note any application block–specific exceptions that can occur during the execution of normal process flow. This list will help you to determine whether or not the design for exception management provides specific exception types where required. Using this approach ensures that the application block can generate meaningful exceptions.

  • Throwing exceptions is expensive; therefore, exceptions should not be used to control application logic flow. Exceptions are best thrown under exceptional situations. For example, if the client of CMAB requests specific information for a key value and no information is returned, this is an expected situation. The application block should not throw an exception. However, if the client requests information, and CMAB fails to connect to persistent storage (such as SQL Server) because of security issues (for example, an Access Denied error), this is a good case for throwing an exception.

    Consider the following code snippet.

    // Bad scenario to throw exception
    static void ConfigExists( string KeyForConfig) {
        //... search for Key
        if ( dr.Read(KeyForConfig) ==0 ) // no record found
        {
            throw( new Exception("Config Not found"));
        }
    }  
      

    These conditions should be handled by returning a simple Boolean value. If the Boolean value is true, the configuration information exists in the database.

    static void ConfigExists( string KeyForConfig) {
        //... search for key
        if ( dr.Read(KeyForConfig) ==0 ) // no record found 
        {
            return false;
        }
        . . .
    }
      
  • Another significant design decision is how functions should report exceptions to the caller. Functions should avoid using error codes as return values or out parameters for two main reasons. First, throwing exceptions ensures notification. Second, clients of an application block must customize their application exception management to suit the nonstandard technique of passing error codes.

    Consider the following code snippet.

    class GetEmployeeDetails{
        public int GetEmployeeName(out string name){
            int errorCode = 0;
            try{
                // Data access logic specific to the application block
                name = SqlHelper.ExecuteNonQuery( );        
            }
            catch( Exception e ) {
                // Perform some exception-related operation like logging or 
                //rollback operations.
    errorCode = 3;    
            }
            finally{
                return errorCode;
            }
        }
    }
    
    public void DisplayName(){
        //Creating an instance of the class that contains the GetEmployeeName 
        //method
        string employeeName; 
        GetEmployeeDetails varDetails = new GetEmployeeDetails(); 
        int errorCode;
        try{
            errorCode = varDetails.GetEmployeeName(out emloyeeName);
            if(errorCode == 3){
                //throw error based on the return code
                //not intuitive
            }
        }
        catch(Exception e){
            //Exception Management Code for all the remaining errors
        }
    }
      

    In the preceding code snippet, an error code is returned instead of an exception. Therefore, the calling function from the client, DisplayName, must change its exception management to handle the error code from the application block.

    Compare this to the following code where, instead of using error codes, the application block throws an exception, which simplifies the exception management code of the client.

    public int GetEmployeeName(out string name){
        try{
            // Data access logic specific to the application block
            name = SqlHelper.ExecuteNonQuery( );
        }
        catch( Exception e ) {
            // Perform some exception related operation like logging or 
            //rollback operations.
            throw new ConfigurationException(.....,e);        
        }
    }
    public void DisplayName(){
        //Creating an instance of the class that contains the GetEmployeeName   \
        //method
        string employeeName; 
        GetEmployeeDetails varDetails = new GetEmployeeDetails(); 
        try{
            varDetails.GetEmployeeName(out emloyeeName);
        }
        catch(ConfigurationException e){
            // more intuitive and standardized
            //Exception Management Code
        }
        catch(Exception e){
            //Exception Management Code
        }
    }
      
  • The design should use a flexible error-reporting mechanism. This mechanism should be configurable so that the client can determine the event sinks for logging of errors based on particular criteria, such as severity. For example, the default configuration of CMAB logs high severity errors in the event log and all the warnings and informational messages in Windows Event Trace.

    This configurable system should also provide the flexibility of turning the reporting mechanism on and off. This reporting system can be very beneficial when debugging an application block; however, because of the performance overhead, it may not be desirable in a production environment.

  • The design for the application block should ensure that in addition to errors, other informational messages are logged and reported by raising appropriate events. These events are useful for monitoring the health of the application block. For example, the CMAB can report any request that holds locks for writing or updating information for more than 3 milliseconds.

More Information

Tools for Architecture and Design Review

The tools available for architecture and design review are as follows:

  • FxCop. This tool can be used to check for compliance of code with various types of guidelines. However, FxCop is of limited help when you are reviewing the design documents for the application block.

For more information about using FxCop and the rules it checks for compliance, see the FxCop Team Page at http://msdn.microsoft.com/en-us/library/bb429476(VS.80).aspx.

Summary

The chapter presented a design review process for application blocks. The process attempts to ensure that all of the functional requirements have been addressed and that the design follows best practices related to performance, security, globalization, maintainability, and extensibility.

Start | Previous | Next

patterns & practices Developer Center

Retired Content

This content is outdated and is no longer being maintained. It is provided as a courtesy for individuals who are still using these technologies. This page may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist.

Did you find this helpful?
(1500 characters remaining)
Thank you for your feedback
Show:
© 2014 Microsoft. All rights reserved.