Software architects generally think in terms of high-level abstractions rather than low-level programming details. Representing a system in terms of high-level abstractions promotes understanding of the system and reduces its perceived complexity. One such set of abstractions is software design patterns. They have been successfully applied in the past to simplify and solve recurring problems in software design.
Given the above, it comes as no surprise that many popular software libraries make extensive use of design patterns so that the APIs can be abstracted out at a high level for the end programmer. The .NET Framework Class Library (FCL) is no exception. Since the FCL builds on the strengths of Microsoft's experience with developing software libraries, one can assume that instances of design patterns found in the FCL are fairly appropriate usages of these patterns. This article describes some instances of a commonly occurring design pattern in the FCL: the Factory Method design pattern.
A detailed description of the Factory Method design pattern can be found elsewhere,
so I will not try to describe it here. Suffice it to say that this
pattern consists of two class hierarchies, one of Products, and one of Creators.
ConcreteCreator class creates instances of specific
using a factory method.
Factory methods are sometimes a more flexible way to instantiate a class than directly calling the constructor of the class, for the following reasons:
The FCL uses factory methods to its advantage in a number of places. Some of them are discussed below.
Iterator interface traverses a collection of objects. The interface aims
to create a way to access the elements in a collection without exposing the
internal structure of the collection. One way to implement this interface would
be to have every collection class return an iterator object supporting a specific
interface for iterating over collections of that particular type only. However,
using this approach, one usually ends up exposing the internal structure of
the collection being traversed. The FCL uses a better approach: it uses a factory
method to return a polymorphic instance of the appropriate iterator class. All
iterators returned by this factory method support a common interface for enumerating
over all collection classes without exposing the internal structure of the collection
being traversed. This has the added benefit of allowing changes to be made to
the collection without requiring a change in the client code.
By specifying a
GetEnumerator factory method in the
IEnumerable interface and by having all collection
classes implement this interface, the framework exposes one interface for obtaining
an enumerator for a collection.
ArrayList is one such class
that implements the
IEnumerator object capable of enumerating over the elements in the
Figure 1 shows the class hierarchy where the
Iterator interface uses the Factory Method pattern.
|Figure 1. Factory Method pattern for obtaining an enumerator
Since an iterator must have knowledge of the internal structure of the class over which
it iterates, it is best to let every class provide its own iterator.
IEnumerable classes provide
their own iterators using
GetEnumerator. In Figure 1,
IEnumerable (the Creator) defines the interface by which an
IEnumerator (the Product) is returned to the client. A
ArrayList) can then be called to return
ArrayListEnumeratorSimple, a private inner class of
which is an
IEnumerator object capable of iterating over an
Clients are required to refer to the returned object by the interface
WebRequest serves as a convenient base class for the .NET Framework's request/response
model for accessing data from the Internet. This class encapsulates the details of
connecting to the server, sending the request, and receiving the response. This means
that an application can participate in request/response transactions in a protocol-agnostic
manner using instances of the
WebRequest class, while protocol-specific classes derived from
WebRequest carry out the details of the request.
The static factory method
WebRequest.Create creates protocol-specific descendants of
WebRequest using the value of the URI passed in as argument. For example, when a URI
beginning with "http://" is passed, an
HttpWebRequest object is returned; when a URI
beginning with "file://" is passed, a
FileWebRequest object is returned.
By default, the .NET Framework supports "http://", "https://", and "file://" URI schemes.
This is easily verified by looking at the
<webRequestModules> section of the
machine.config file in the .NET Framework installation's CONFIG directory:
<webRequestModules> <add prefix="http" type="System.Net.HttpRequestCreator, .../> <add prefix="https" type="System.Net.HttpRequestCreator, .../> <add prefix="file" type="System.Net.FileWebRequestCreator, .../> </webRequestModules>
This section implies that
System.Net.HttpRequestCreator is responsible for creating
objects for request URIs beginning with "http" and "https", and
is responsible for creating
WebRequest objects for request URIs beginning with "file". Both of
these classes implement the
System.Net.IWebRequestCreate interface, which contains only one
WebRequest Create(Uri uri);
|>Figure 2. Factory Method pattern used for creating a
Figure 2 illustrates the Factory Method pattern used to obtain a
WebRequest instance for
"http://"- and "https://"-type URIs.
WebRequest.Create delegates creation of the appropriate
WebRequest (the Product) object to an
IWebRequestCreate object (the Creator).
ConcreteCreator) is then called to return an instance of
ConcreteProduct). This design is interesting because it contains two
IWebRequestCreate. Even though
is the Creator visible to the client, it is
IWebRequestCreate that decides which derived
object to return. The
IWebRequestCreate interface is internal to the
assembly by intention, so the only way to create an instance of
WebRequest is by calling
WebRequest.Create is a parameterized factory method -- it takes a parameter
that identifies the type of object to create, and all objects created are of type
The .NET Framework contains a rich and extensible collection of cryptography classes that you
can use within your own programs, right out of the box. Cryptography classes are part of the
System.Security.Cryptography namespace. These classes use the Factory Method pattern
to decouple the choice of algorithms used from their specific implementations.
are the three roots of the class-inheritance hierarchy in the cryptography framework. These are
abstract classes from which specific implementations of various encryption algorithms are derived.
Each of these classes supports a static factory method called
Create, which creates
a particular instance of the cryptography class based on the type of algorithm requested.
For example, the following line will instantiate a
DESCryptoServiceProvider, which is the default implementation of the Data
Encryption Standard (DES) algorithm in the .NET Framework.
// Return an instance of DESCryptoServiceProvider SymmetricAlgorithm s = SymmetricAlgorithm.Create("DES");
The mapping between the string arguments and the instantiated classes can be found here.
SymmetricAlgorithm.Create is a parameterized
factory method; it takes a parameter that identifies the type of object to create, and all
objects created are of type
SymmetricAlgorithm. The use of a parameterized factory method
here is important because it provides opportunities for extending the cryptography framework.
For example, by adding a mapping for the RC5 algorithm (which does not currently exist in the .NET Framework SDK) that returns an instance of, say,
can add an RC5 implementation to the existing framework, and instantiate it using the following line:
// Return an instance of RC5CryptoServiceProvider SymmetricAlgorithm s = SymmetricAlgorithm.Create("RC5");
The code-access security model implemented by the CLR requires every assembly to pass through
a security checkpoint at the time of loading. This involves granting privileges to the code
based on the origin of the assembly, digital signatures on the assembly, custom evidence attached
to the assembly, requests made by the assembly, and so on. Evidence is presented by the assembly
in the form of a
System.Security.Policy.Evidence object, which is a collection of evidence objects
Evidence objects) like
Each evidence object can possibly create an identity permission that is added to the grant set of
the assembly. Therefore, for all pieces of evidence that implement the
interface, the corresponding identity permission is obtained and added to the grant set of the
|Figure 3. Obtaining a collection of
Figure 3 shows the class diagram for a case where an assembly presents only a
System.Security.Policy.Url object, which is evidence of the URL from where the assembly originates.
This evidence object is encapsulated in a
System.Security.Policy.Evidence collection, which is
then passed to the
CreateIdentityPermission method of
CreateIdentityPermission method has the following signature:
System.Security.IPermission CreateIdentityPermission( System.Security.Policy.Evidence evidence);
The .NET security framework calls the Factory Method
CreateIdentityPermission on the appropriate implementation of
IIdentityPermissionFactory to get an
IPermission object that represents that piece of evidence.
If multiple evidence objects are involved, then during policy resolution the runtime calls
CreateIdentityPermission on all evidence objects that implement
grants the resulting identity permissions to the appropriate assembly in the form of a
object, which is simply a collection of
The Factory Method pattern used in the above framework abstracts out the policy resolution process
to the highest level, where the client (typically the
SecurityManager.Resolve method, as shown below)
takes in a
System.Security.Policy.Evidence object and gets back a
Evidence evidence = new Evidence(); ..... PermissionSet permissionSet = SecurityManager.ResolvePolicy(evidence);
The mechanism of identifying the evidence types and creating
representing those evidence types is completely transparent to the client.
Several instances of the Factory Method pattern can be found in the ASP.NET HTTP pipeline. The ASP.NET
HTTP pipeline is a set of classes (in the
System.Web namespace) that a web server uses to process
an incoming HTTP request and return a response to the client. The pipeline takes care of session
management, application pooling, caching, security, etc.
At every point in the pipeline, the objective is to advance the request processing by one step by either identifying the objects that can handle the incoming request, or by forwarding the request to objects capable of handling the request. Factory methods come into play when different types of objects need to be instantiated, based on the type of incoming request.
The entry point in the pipeline is the
HttpRuntime object, which creates an instance of
HttpContext for the particular request.
does not try to determine the type of
HttpApplication object that will handle the request. Instead,
it calls the static factory method
passing it the
HttpContext instance just created.
HttpApplicationFactory is an
undocumented class that contains the logic required to determine the
capable of handling an incoming request.
GetApplicationInstance uses the
instance to determine the virtual directory (i.e., application) that this request was sent to.
If the virtual directory has been called before, then the
HttpApplication object (or a derived
ASP.Global_asax object, if Global.asax is defined) is returned from the pool of applications.
Otherwise, a new
HttpApplication object for that virtual directory is created and returned.
Figure 4 shows the class diagram for instantiating an
HttpApplication object capable of handling
|Figure 4. Fetching the appropriate
HttpApplicationFactory.GetApplicationInstance is a parameterized factory method. It takes a parameter that identifies the type of product to create, and all products created are of type
Moving farther along in the pipeline, the
HttpApplication instance just created needs the object
that can handle the type of resource requested. This object is called a handler. To look up the
proper handler, the
HttpApplication first determines the factory that can create the handler. It
does that by looking up the
<httphandlers> section of the machine.config file. If it's not found in
machine.config, it looks up the application's web.config file, using the inherited configuration
<httpHandlers> section in these config files lists the handlers currently registered
for the application. A part of this section is reproduced below.
<httpHandlers> <add verb="*" path="*.aspx" type="System.Web.UI.PageHandlerFactory" /> <add verb="*" path="*.ashx" type="System.Web.UI.SimpleHandlerFactory" /> ..... </httpHandlers>
This section shows the mapping between the type of resource requested and the class capable of
creating a handler for that resource. If an .aspx page is requested, the
class will be called. Once this class has been located,
HttpApplication invokes the
method on the
IHttpHandlerFactory interface to retrieve a new instance of the handler class. All such
factory classes must implement the
IHttpHandlerFactory interface. These factory classes have no behavior
except to dynamically manufacture new
IHttpHandler objects using the
GetHandler method. This method
IHttpHandler object, which in this example is the
System.Web.UI.Page-derived class created
from the .aspx file. For an .aspx file called SamplePage.aspx, the compiled class will be called
ASP.SamplePage_aspx, as shown in Figure 5. This class serves as the endpoint for the request, and
is responsible for populating the response buffer for that particular request.
|Figure 5. Factory Method pattern used for obtaining the appropriate
IHttpHandlerFactory.GetHandler is a classic example of the Factory Method pattern, where
IHttpHandlerFactory (the Creator) decides which
IHttpHandlerFactory-derived object to create,
which is returned as an
IHttpHandler (the Product) object.
The Factory Method pattern is probably the most commonly found design pattern in the FCL. This article has presented a few notable instances of the use of this pattern in the FCL. If you begin to explore, you will probably find many more instances. Identifying those instances and understanding the motivation for their use can provide useful insights into your own designs.
Amit Goel has been developing object-oriented applications for several years. You can learn more about him at www.amitgoel.com.
Return to ONDotnet.com
Copyright © 2009 O'Reilly Media, Inc.