| Consider | Providing aggregate components for commonly used feature areas. | 
        | Do | Model high-level concepts (physical objects) rather than system-level tasks with aggregate components. | 
        | Do | Increase visibility of aggregate components by giving them names that correspond to well-known entities of the system, such as MessageQueue, Process, or EventLog. | 
        | Do | Design aggregate components so they can be used after very simple initialization. | 
        | Do Not | Require the users of aggregate components to explicitly instantiate multiple objects in a single scenario. | 
        | Do | Make sure aggregate components support the Create-Set-Call usage pattern, where developers expect to be able to implement most scenarios by instantiating the component, setting its properties, and calling simple methods. | 
        | Do | Provide a default or a very simple constructor for all aggregate components. | 
        | Do | Provide properties with getters and setters corresponding to all parameters of aggregate component constructors. | 
        | Do | Use events instead of delegate-based APIs in aggregate components. | 
        | Consider | Using events instead of virtual members that need to be overridden. | 
        | Do Not | Require users of aggregate components to inherit, override methods, or implement any interfaces in common scenarios. | 
        | Do Not | Require users of aggregate components to do anything besides writing code in common scenarios. | 
        | Consider | Making changes to aggregate components' modes automatic. | 
        | Do Not | Design factored types that have modes. | 
        | Consider | Integrating your aggregate components with Visual Studio Designers. | 
        | Consider | Separating aggregate components and factored types into different assemblies. | 
        | Consider | Exposing access to internal factored types of an aggregate component. | 
        | Do | Use the following convention for defining APIs for asynchronous operations: 1. public <return> Operation(<parameters>, <out params>) 2. public IAsyncResult BeginOperation(<parameters>, AsyncCallback callback, object state) 3. public <return> EndOperation(IAsyncResult asyncResult, <out params>) | 
        | Do | Ensure that the return type of the Begin method implements IAsyncResult. | 
        | Do | Ensure that any by-value and ref parameters of the synchronous method are represented as by-value parameters of the Begin method. | 
        | Do | Ensure that the return type of the End method is the same as the return type of the synchronous method. | 
        | Do | Ensure that any out and ref parameters of the synchronous method are represented as out parameters of the End method. | 
        | Do Not | Continue the asynchronous operation if the Begin method throws an exception. | 
        | Do | Notify the caller that the asynchronous operation completed via all of the following mechanisms in this order: 1. Set IAsyncResult.IsCompleted to true. 2. Call the async callback. | 
        | Do | Throw from the End method to indicate that the asynchronous operation could not complete successfully. | 
        | Do | Complete all remaining work synchronously once the End method is called. | 
        | Consider | Throwing an InvalidOperationException if the End method is called with the same IAsyncResult twice, or if the IAsyncResult was returned from an unrelated Begin method. | 
        | Do | Set IAsyncResult.CompletedSynchronously to true if and only if the async callback will be run on the thread that called Begin. | 
        | Do | Implement the Basic Dispose Pattern on types containing instances of disposable types. | 
        | Do | Implement the Basic Dispose Pattern and provide a finalizer on types holding resources that need to be freed explicitly and that do not have finalizers. | 
        | Consider | Implementing the Basic Dispose Pattern on classes that themselves don't hold unmanaged resources or disposable objects but are likely to have subtypes that do. | 
        | Do | Declare a protected virtual void Dispose(bool disposing) method to centralize all logic related to releasing unmanaged resources. | 
        | Do | Implement the IDisposable interface by simply calling Dispose(true) followed by GC.SupressFinalize(this). | 
        | Do Not | Make the parameterless Dispose method virtual. | 
        | Do Not | Declare any overloads of the Dispose method other than Dispose() and Dispose(bool). | 
        | Do | Allow the Dispose(bool) method to be called more than once. | 
        | Avoid | Throwing an exception from within Dispose(bool) except under critical situations where the containing process has been corrupted (leaks, inconsistent shared state, etc.). | 
        | Do | Throw an ObjectDisposedException from any member that can not be used after the object has been disposed. | 
        | Consider | Providing method Close(), in addition to the Dispose(), if close is standard terminology in the area. | 
        | Avoid | Making types finalizable. | 
        | Do Not | Make value types finalizable. | 
        | Do | Make a type finalizable, if the type is responsible for releasing an unmanaged resource that does not have its own finalizer | 
        | Do | Implement the Basic Dispose Pattern on every finalizable type. | 
        | Do Not | Access any finalizable objects in the finalizer code path, as there is significant risk that they will have already been finalized. | 
        | Do | Make your Finalize method protected. | 
        | Do Not | Let exceptions escape from the finalizer logic, except for system-critical failures. | 
        | Consider | Creating and using a critical finalizable object (a type with a hierarchy that contains CriticalFinalizerObject) for situations in which a finalizer absolutely must execute even in the face of forced application domain unloads and thread aborts. | 
        | Do | Prefer constructors to factories, as they are generally more usable, consistent, and convenient than specialized construction mechanisms. | 
        | Consider | Using a factory if you need more control than can be provided by constructors of the creation of the instances. | 
        | Do | Use a factory in cases where a developer might not know which type to construct, such as wen coding against a base type or interface. | 
        | Consider | Using a factory if having a named method is the only way to make the operation self-explanatory. | 
        | Do | Use a factory for conversion-style operations. | 
        | Do | Prefer implementing factory operations as methods, rather than properties. | 
        | Do | Return created instances as method return values, not as out parameters. | 
        | Consider | Naming factory methods by concatenating Create and the name of the type being created. | 
        | Consider | Naming factory types by concatenating the name of the type being created and Factory. | 
        | Consider | Using the Optional Feature Pattern for optional features in abstractions. | 
        | Do | Provide a simple Boolean property that clients can use to determine whether an optional feature is supported. | 
        | Do | Use virtual methods on the base class that throw NotSupportedException to define optional features. | 
        | Avoid | Making public members virtual. | 
        | Consider | The Template Method Pattern to provide more controlled extensibility. | 
        | Consider | Naming protected virtual members that provide extensibility points for nonvirtual members by suffixing the nonvirtual member name with “Core”. | 
        | Do | Prefer method parameters as the mechanism for users to provide timeout time. | 
        | Do | Prefer using TimeSpan to represent timeout time. | 
        | Do | Throw System.TimeoutException when a timeout elapses. | 
        | Do Not | Return error codes to indicate timeout expiration. |