Article Author: Dhiwakar Kusuma
Introduction
The Enterprise Library is Microsoft’s initiative for promoting reusability of standards and best practices for technology, and constitutes seven application blocks. The first article of this series examined
- Data Access
- Exception Handling
- Configuration
In this article I’ll move on to discuss the remaining blocks:
System Requirements
The current version of Enterprise Library is fully supported in Visual Studio .NET 2003. A VS2005 version is to be released shortly. Following are the system requirements for trying out the sample code available for download:
- Visual Studio.NET 2003
- .NET Framework version 1.1
- Enterprise Library
- SQL Server 7.0 or above (Optional requirement in blocks were persistent DB store could be used)
- NUnit 2.2
Installing and Compiling the Sample Code
The code sample, available for download contains one folder for each application block sample. After extracting, you can open the solution file that is present in each of the folder and build it. It is suggested that you read the article and explore the code in parallel as you might get stuck in configuring the application.
Introduction to Blocks
The remainder of this article will concentrate on providing a high level overview of the four remaining blocks of the Enterprise Library that were not described on part 1.
The Logging and Instrumentation Block
These days, logging and instrumentation has become an integral part of most applications. It is often required by the production support team in order to capture reproducible steps for debugging a system failure.
Often times logging is confused with the term instrumentation. Instrumentation is the ability to monitor your application so that sufficient data will be available to diagnose an issue. For example when your application fails to work correctly, you can check the trace information to find out the reason for the application’s malfunctioning. Logging on the other hand will contain minimal information like starting and halting of an activity.
Previously the Enterprise Instrumentation Framework (EIF) was introduced by Microsoft Corporation in 2003 for the sole purpose of instrumenting an application developed in .NET. EIF will be discontinued and is replaced moving forward by the Logging and Instrumentation block.
Features
- Many destinations are available under the Enterprise Library Application block – the event log, a database, a text file, MSMQ, email and WMI.
- Provision for setting the log category and priority to support debugging and to providing information.
- Formatters, both inbuilt and custom formatters that help to format the appearance of the logs that are written.
- Provision for logging in synchronous and asynchronous fashion. For asynchronous logging one should choose MSMQ as the distribution strategy through the configuration GUI.
- Options are available for including extra named fields. Developers can identify the extra data, fields and value pairs, which are to be written by passing an object that implements the iDictionary interface, as one of the parameters to the Logger.Write() static method.
Note: When using EmailMessage sink, do note that there is no provision for placing your own subject line out of the box. You can see this in EmailMessage.cs → CreateMailMessage() function.
Design
I’m sure that everyone will want to make use of this block just because of its ease and configurability to divert the logs to many different destinations. Once you have configured the logging you just need to call the static Write() function of the Logger class. Logger internally will create an instance of the LogWriter and call its Write() function. LogWriter will make sure of whether or not to write the logs, where to write and what logs are to be written and what logs are not to be written / skipped.

Figure 1. Class diagram for the Logger Class
Custom sinks can be created by deriving from LogSink and implementing the IConfigurationProvider interface. You can also create your own distribution strategy by extending the ILogDistributionStrategy interface. This interface is available in the Microsoft.Practices.EnterpriseLibrary.Logging.Distributor namespace.
You can extend ILogSink , used by ILogDistributionStrategy , for creating custom sinks.
Building the Sample Code
This sample will show how simple it is to use the logging application block. Start by creating a VS.NET solution and a project. In the Visual Studio solution go to the project properties, in the Common Properties → Build Events – set the following value copy "$(ProjectDir)*.config" "$(TargetDir)" in Post -build event command line . This is required for the enterprise library configuration files to get copied to the bin directory on each build. Next add an app.config file to the project.
Now Open the Enterprise Library Configuration through the Enterprise Library programs menu. Choose the app.config that you had added earlier through File → Open menu. Right click the application node that appears and from the context menu choose New → Logging and Instrumentation Application Block . This action will add nodes related to Configuration and Logging Application Block .
By default logging is enabled and tracing is not. Since the demo is going to concentrate both on logging and tracing, let’s enable it by setting the value of TracingEnabled to True . This property is available in Logging and Instrumentation Application Block → Client Settings. Choose File → Save All in the Configuration GUI and return to the VS.NET. This completes the configuration settings.
Next we need to add a reference to Microsoft.Practices.EnterpriseLibrary.Logging.dll . This component is available under Program FilesMicrosoft Enterprise Librarybin by default. Add the following using clause at the top of the form’s code:
using Microsoft.Practices.EnterpriseLibrary.Logging;
Now create a button on the default form of the application and within its click event, add the following code:
LogEntry le = new LogEntry();
le.Category = "General";
le.Priority = 0;
le.TimeStamp = System.DateTime.Now;
le.Title = "Log button clicked";
le.Message = "The user clicked on the Log button";
Logger.Write(le);
The above code shows how to write an event log entry. By default there are two distribution setting categories, one that writes the log entry (trace) to the event log and the other that writes it to a file system (general). As you can see from the code I have specified the Category as General which points to the distribution strategy that relates to event logging. After executing the code, click on the button and check the event log, you will find an entry similar to the one found in Figure 2.

Figure 2. The Event log generated by the sample
You can modify the distribution strategy Category to Trace and the log will be generated in the application root which is the Bin directory if you are using VS.NET. The name of the file by default is configurable through the configuration GUI, is Trace.log . Next I will show how you can use the tracing functionality provided by the logging and instrumentation application block. Since I have enabled the tracing already, I am going to jump to the code. What I am going to do is to trace the performance aspects of the previous code. Firstly, append another using clause in the form’s code
using Microsoft.Practices.EnterpriseLibrary.Logging.Tracing;
Next modify the button click code as follows:
using (new Tracer("Trace", "Tracing the performance of event logging"))
{
LogEntry le = new LogEntry();
le.Category = "General";
le.Priority = 0;
le.TimeStamp = System.DateTime.Now;
le.Title = "Performance Tester";
le.Message = "Eventlog using Application Block";
Logger.Write(le);
}
As you can see, I enclosed the code that has to be traced within a Using clause that creates a new Trace object with the Category as Trace so that the trace gets generated to the trace.log file. When you execute the above code and open the trace.log file from the application startup path you should see a trace similar to the one in Figure 3.

Figure 3. Trace generated from the sample application
The details from the trace can help in determining performance of an application. Let me briefly describe what the code does. The Using clause limits the scope of the objects availability. Thus it destroys or disposes the object, in this case the new Trace object, after the execution of the code that is present within the Using clause. The logging and instrumentation block makes sure that the trace information is flushed when the Trace object is disposed.
The Security Block
There are two main concepts that one should know when it comes to security – authentication and authorization. Authentication checks if a user is valid (this is done mostly by validating a username and password) whereas authorization checks whether the user has permissions to perform the action that they intend to do.
When it comes to authorization, it becomes difficult to manage the rights / permissions individually and hence the users are often grouped together using r oles . Users are mapped to one or more roles and permissions are assigned to the role instead of the users. This way maintenance becomes much easier.
The security block is the new version of the authorization and profile application block from the prior release. One of the most important features that got added, apart from the ones listed below, is the introduction of authentication feature (not available in authorization and profile application block). By default this block authenticates users against a database. As extensibility was one of the main objectives of developing the enterprise library, one can create their own authentication provider for validation against a different data store.
Features
- Covers the following aspects of security – authentication, authorization, role management, profile management, security caching and session management
- Can plug-into the data access block for database access
- Can plug-into the cryptography block for hashing purpose
- Authentication tokens are generated for user identification
- The following authorization providers are supported Authorization rule where you can create regular expression like rules and store the same in the configuration file. Also AzMan (Authorization Manager) which comes with Windows 2000 Server with SP4, Windows 2003 server, or Windows XP SP1 with Windows Server 2003 Administration Tools Pack.
- Can use both Active Directory and a database as role providers. The database schema for database role provider is included.
Design
Authentication is a simple two step process. Firstly, you create an AuthenticationProvider object through the AuthenticationFactory , which creates an instance based on the provider name you pass as the parameter. The configuration block is used for mapping this provider name with the providers that you have configured through the enterprise library configuration UI.
Secondly, call the Authenticate() function of the AuthenticationProvider instance created above with the credentials for validation. An Identity object is returned through the out variable, that you pass in the Authenticate() methodif authentication succeeds otherwise a null value is returned.

Figure 4. Authentication class diagram
Building the Sample Code
To provide an example that can be tried out, I’m going to manage all my roles in the database as some people may not have Active Directory on their home systems. Follow the below given steps to setup the sample application:
From the Enterprise Library programs menu select Build Enterprise Library. Click Enterprise Library Program menu→ Application Blocks for .NET -> Security Application Blocks -> Install Security Database . This will install the security database on the local server by default. If you wish to install the DB in a different location, you can run the script available at Program FilesMicrosoft Enterprise LibrarysrcSecurityDatabaseScripts directory . Since I am planning to store the user and role related information in the database, this database is mandatory. From the same menu location choose Security Design VS.NET 2003 solution . This application helps in populating the security database created above with users and roles. The solution is pointing to the local system security database and hence requires no change.
If you have installed the security database on a different system, once the database is created you can open the configuration file of the solution in the Configuration GUI and edit the connection string. Next Run the VS.NET solution after making sure that Tools.SecurityDatabaseConsole is set as the startup project.
In the Database Authentication Provider field select Security Database Authentication Provider from the list box at the top of the Window and click on the Connect button. Once the connection is made successfully the list boxes and buttons will be enabled. A screen shot (see Figure 5) of the admin console is provided for reference purpose.

Figure 5. The security database administration console used for creating users and roles in the security database
Start by creating a single role named AdminRole by clicking on the New Role button and add two users Dhiwakar and Unknown using the New User button. I will add Dhiwakar to the AdminRole by selecting Dhiwakar from the All Users list and clicking on the <<< button . Close the console. Now that the roles and users are setup, we will create a simple client application that will help in authenticating and authorizing the user based on the information available in the security database.
Start by creating a Windows forms application and adding the following references to the project:
Microsoft.Practices.EnterpriseLibrary.Security.dll
Microsoft.Practices.EnterpriseLibrary.Security.Database.Authentication.dll
Microsoft.Practices.EnterpriseLibrary.Configuration.dll
Add an app.config file to the project, then go to the project properties, in the Common Properties → Build Events – set the following value copy "$(ProjectDir)*.config" "$(TargetDir)" in Post-build event command line . This is required for the enterprise library configuration files to get copied to the bin directory on each build. Open this config file using Configuration GUI, in the Configuration GUI right click the application node that appears and select New → Security Application Block . This action will generate a set of nodes for you to use. Next we need to set the provider, select Cryptography Application Block → Hash Providers then right click and click New → Hash algorithm provider and select the algorithm that suits you, in the sample application I chose SHA1Managed .
The data access application block provides values for the Database and Server nodes. The Database node value should be Security and the value of the Server should be the server instance where the security database is installed. Right click Security Application Block → Authentication and select New → Database Authentication Provider . In the Database Provider node that appears, select the HashProvider value as the one that you had created in the above steps. Next, save all the configuration and exit the console.
Design a form similar to the one shown below in Figure 6.
Figure Image6.gif Sample application for authenticating using the security application block
In the button’s click event for the Validate Inputs button add the following code to validate the authenticity of the username and password against the entries made in the security database. If the user is valid then check if the user is part of the role entered in the Role To Check field.
private void ValidateInputs_Click(object sender, System.EventArgs e)
{
//Authenticate user
IAuthenticationProvider authProvider = AuthenticationFactory.GetAuthenticationProvider("Database Provider");
NamePasswordCredential credentials = new NamePasswordCredential(UserName.Text,Password.Text);
System.Security.Principal.IIdentity identity;
authProvider.Authenticate(credentials, out identity);
if (identity != null) MessageBox.Show("Authenticated Succeeded");
else
{ MessageBox.Show("Authentication Failed"); return;
}
/Proceed with checking the role to which the identity belongs
IRolesProvider rp = RolesFactory.GetRolesProvider("Role Database Provider");
System.Security.Principal.IPrincipal principal = rp.GetRoles(identity); //Returns the security context – Principal
if (principal.IsInRole(RoleName.Text)) MessageBox.Show("Yes, User is in role mentioned.");
else MessageBox.Show("Nope, user doesn’t belong to the role mentioned.");
}
Now you can run the run the application and experiment with different values to see the results.
The Cryptography Block
Derived from the Greek work Kryptos, cryptography is the science of hiding information. As far as information technology is concerned we have been mainly focusing on encryption which deals with scrambling the information so the information is no more readable / understandable unless decryption takes place.
This is a new application block which greatly helps the developer in implementing encryption without worrying much of the code that goes into implementing a specific algorithm. With a simple to use interface, the enterprise library configuration UI, one can bring cryptographic capability to an application. Also, changing the algorithm that is being used is also simple – one can easily give the user of the application the ability to choose between a wide variety of algorithms that are available out of the box.
Features
- Abstraction from the algorithm / APIs. This is of great help as the application code remains the same for various cryptography algorithms
- Enterprise library cryptography application block supports hashing, encryption / decryption, DPAPI (Data Protection API) and other symmetric algorithms
- By choosing a symmetric algorithm provider you can choose the algorithms that come along with the .NET framework or you can provide your own implementation thus making the cryptography block extensible.
- Acts as a pluggable component for security application block.
- Completely configurable, you can choose the algorithm using the configuration block / UI thus avoiding any coding changes for using a different algorithm.
Very simple to use, there are only four methods, overloaded to accept both string and byte array as input, at the top level namely CreateHash() , CompareHash() , EncryptSymmetric() , and DecryptSemmetric()
Design
The Cryptography components act as a faade for SymmetricCryptoProvider and HashProvider by providing static overloaded functionalities for both hashing and encryption. When the static functionalities, like CreateHash() , CompareHash() , EncryptSymmetric() , and DecryptSymmetric() of the Cryptographer class are called appropriate factory classes, SymmetricCryptoProviderFactory for encryption and HashProviderFactory for hashing are instantiated and an instance of ISymmetricCryptoProvider or IHashProvider is retrieved. Using this instance the functionalities for encryption and hashing are called / used. Below is a class diagram which represents the relationship between the various classes.

Figure 7. Cryptography class diagram
Keywords
- Symmetric algorithms – This type of algorithms uses a single key both for encryption and decryption. They consume less processing time when compared to asymmetric algorithms. Since cryptography in our applications is being used for saving some valuable data symmetric algorithms are of ideal choice. Symmetric algorithms can be extended by creating a class that implements ISymmetricCryptoProvider .
- HashProviderFactory – Factory class for creating instances of IHashProvider .
Building the Sample Code
The sample application will demonstrate how to use the encrypt / decrypt functionality provided by the cryptography block.
Start by creating a VS.NET solution and a Windows Forms project. Add an app.config file to it. In the Visual Studio solution go to the project properties, in the Common Properties → Build Events – set the following value copy "$(ProjectDir)*.config" "$(TargetDir)" in the Post-build event command line . This is required for the enterprise library configuration files to get copied to the bin directory on each build.
Open the Enterprise Library Configuration through the Enterprise Library programs menu. Choose the app.config that you had added earlier through File → Open menu. Right click the application node that appears and from the context menu choose New → Cryptography Application Block . This action will add nodes related to configuration application block to the file.
Right click the Symmetric Providers and click New → DPAPI Symmetric Cryptography Provider . In the dialog that appears click on Machine and click on the OK button. This action will make sure that the encrypted text can be decrypted on the machine in which it was originally encrypted. Choose File → Save All in the Configuration GUI and return to the VS.NET. This completes the configuration settings.
Next add reference to the Microsoft.Practices.EnterpriseLibrary.Security.Cryptography.dll file. This component is available at Program FilesMicrosoft Enterprise Librarybin by default. Add the following using clause at the top of the form’s code
using Microsoft.Practices.EnterpriseLibrary.Security.Cryptography;
Create a form with two text boxes and buttons, one pair for encryption and the other for decryption as shown in Figure 8.

Figure 8. UI for the crypto sample
In the Encrypt buttons click event add the following code:
EncryptedContent.Text
= Cryptographer.EncryptSymmetric
("DPAPI Symmetric Cryptography Provider",
DecryptedContent.Text);
In the Decrypt buttons click event add the following code:
DecryptedContent.Text
= Cryptographer.DecryptSymmetric
("DPAPI Symmetric Cryptography Provider",
EncryptedContent.Text);
Run the application and place some text in the first text box that takes / shows decrypted content and click on the Encrypt button. The decrypted text will be shown in the text box below as shown in Figure 9.
Figure Image9.gif The cryptography block in action
The Caching Block
This is a relatively new block that got introduced with the enterprise library for the first time. Caching is a great feature for improving scalability and performance. Resources that are at remote locations are usually cached to reduce the load time and network traffic. The ASP.NET cache has been a great hit for those who were developing web related projects as it demonstrated significant increases in the performance of their applications. The caching block has been created with a slightly different objective in mind. Firstly it provides a consistent way in which caching can be implemented in web and Windows applications. The configurability of the caching block makes it easy for the administrator / client / developer to customize the cache location without changing / redeploying any code.
If you are worried about deciding between using the standard ASP.NET caching and the enterprise library caching block, there is a pleasant surprise. Performance wise there aren’t any major differences between ASP.NET caching and the enterprise library caching blocks. So, wherever you have been using ASP.NET caching objects you can continue to use the same with out any worries. Both of the architectures are based on Microsoft’s caching architecture (Link provided in the references section for more information).
Features
- Supports offline operations.
- Pluggable and configurable data store for caching data. You can cache data either in persistent stores like a database or in a file system on a separate isolated machine or you can store the cache in non persistent form such as internal memory.
- Configurable expiration policy guarantees that you have control over when you want to stamp the cache as stale so as to refresh the cache. There are two ways by which you can configure the expiration policy – you can either declare the absolute expiration time or you can enable call back routines that notify you based off file / directory changes. Note that the second type involves triggering a separate thread to detect changes and are not based on Watcher pattern employed by Directory Watcher component.
- Provision for creating your own custom expiration policy and support for data stores.
- Thread safety and synchronizing the cache data across threads is guaranteed.
Design
The client application uses the GetCacheManager() function available in the factory class CacheFactory . The CacheManager instance encapsulates the methods that are available in the Cache class. The Cache class uses an implementation of IBackingStore , for storing the cache. It also serves as an extension point for creating your own cache store. For storing the cache in a database you will have to use DataBackingStore which is available as a separate component – Microsoft.Practices.EnterpriseLibrary.Caching.Database.dll and uses the data access application block.
Interestingly the ICacheOperations which is implemented in the Cache class only has a GetCurrentCacheState() and RemoveItemFromCache() .
The cache data is packaged as a CacheItem . CacheItem contains caching data along with the key value, Item’s priority, and Expiration policy.

Figure 10. Caching class diagram
Keywords
- Cache Manager – provides a wrapper for dealing with all the cache related functionalities.
- Cache Manager Factory – helps in procuring an instance of the CacheManager .
- Cache – is the core class of the caching application block.
- Cache Factory – uses GetCacheManager() of CacheManagerFactory to create and return a CacheManager .
- Backing store – helps in managing the cache. Out of the Box you get 3 backing stores namely, the Null backing store that helps in managing the cache in memory, Data backing store that maintains the cache in a database with the help of the data access application blocks and finally the Isolated Storage backing store that stores the cache in the form of a Tree structure.
- Storage Encryption Provider – both the Data and Isolated Storage backing store use the Storage Encryption Provider, part of the Cryptography application block, to encrypt the cache before saving.
- Expiration Policy – defines when the cache is to be made stale and removed from the Backing store. The following are the policies available that can be used while adding an item to the cache: AbsoluteTime , SlidingTime , FileDependency and NeverExpired .
- BackgroundScheduler – an object that periodically monitors the lifetime of items in the cache and performs any clean up operation and, optionally, notifies the application that the item will be expired. If the number of items in the cache is less that the number set in the configuration (Can be seen in Caching Application Block → Default Cache Manager → MaximumElementsInCacheBeforeScavenging through configuration GUI)
- PollTimer – responsible for kick starting the BackgroundScheduler on predetermined limit set in the configuration file.
- CacheItemPriority – used for setting the priority of the item that you are placing in the cache. There are 5 levels of priority namely None, Low, Normal, High, and Not Removable, in the ascending order of priority.
Building the Sample Code
The following code demonstrates how we can cache data using the caching application block. For the purpose of demonstration I am going to use the data access application block too.
Start by creating a VS.NET solution and a Windows form project. Add an app.config file to it. In the Visual Studio solution go to the project properties, in the Common Properties → Build Events – set the following value copy "$(ProjectDir)*.config" "$(TargetDir)" in Post-build event command line . This is required for the enterprise library configuration files to get copied to the bin directory on each build.
Next open the Enterprise Library Configuration through the Enterprise Library programs menu. Choose the app.config that you had added earlier through File → Open menu. Right click the application node that appears and from the context menu choose New → Data Access Application Block . This action will add nodes related to the configuration application block and data access application block.
Inside Data Access Application Block → Connection strings → Sql Connection String , change the values for the Database and Server nodes so that it points to your Northwind database. Inside the Data Access Application Block → Database Instances → Database Instance c hange the name of this node to Northwind DB Instance. Change the Data Access Application Block → DefaultInstanceNode value to the Northwind DB Instance.
Now we need to add a new caching application block from the application nodes’ context menu. Yes, that is all you need for in memory caching. Choose File → Save All in the Configuration GUI and return to the VS.NET.
Next we need to add references to Microsoft.Practices.EnterpriseLibrary.Configuration.dll , Microsoft.Practices.EnterpriseLibrary.Common.dll , Microsoft.Practices.EnterpriseLibrary.Caching.dll , and Microsoft.Practices.EnterpriseLibrary.Data.dll . These components will be available under Program FilesMicrosoft Enterprise Librarybin by default.
Lastly we need to design a form that looks similar to the one shown in Figure 11 below. It will have a drop down list box for populating the list of employees, command buttons for getting the employee details and clearing the cache content, and text boxes for displaying the employee details.

Figure 11. Data Caching sample UI
Add the following in the using section of the form’s code:
using Microsoft.Practices.EnterpriseLibrary.Data;
using Microsoft.Practices.EnterpriseLibrary.Caching;
Here is the event handling code:
private void ClearCache_Click(object sender, System.EventArgs e)
{ //Clears the cache entries.. CacheManager cm = CacheFactory.GetCacheManager(); cm.Flush();
}private void PopulateEmployees()
{ StringBuilder employeeFullName; Database northwindDB = DatabaseFactory.CreateDatabase("Northwind DB Instance"); string selectSQL = "SELECT FirstName, LastName FROM EMPLOYEES"; EmployeesList.Items.Clear(); Using (IDataReader dr = northwindDB.ExecuteReader(System.Data.CommandType.Text,selectSQL)) { while (dr.Read()) { employeeFullName = new StringBuilder(); employeeFullName.Append(dr["FirstName"]); employeeFullName.Append(" "); employeeFullName.Append(dr["LastName"]); EmployeesList.Items.Add(employeeFullName.ToString()); } }
}
private EmployeeDetails GetEmployeeDetails(string employeeFullName)
{ //Gets the details of an employee based on the last and first name Database northwindDB = DatabaseFactory.CreateDatabase("Northwind DB Instance"); string selectSQL = "SELECT EmployeeID, FirstName, LastName, Title, City FROM EMPLOYEES WHERE FirstName + ‘ ‘ + LastName = ‘" + employeeFullName + "’"; EmployeeDetails ed = new EmployeeDetails(); using (IDataReader dr = northwindDB.ExecuteReader(System.Data.CommandType.Text,selectSQL)) { while (dr.Read()) { ed.EmployeeID = dr["EmployeeID"].ToString(); ed.FirstName = dr["FirstName"].ToString(); ed.LastName = dr["LastName"].ToString(); ed.Title = dr["Title"].ToString(); ed.City = dr["City"].ToString(); } return ed; }
}
private void GetDetails_Click(object sender, System.EventArgs e)
{ //Gets the details either from the cache, if it is available, //or from the database. Note that in this example, it is assumed //that the Lastname + firstname is unique for an employee. FirstName.Text = ""; LastName.Text = ""; Title.Text = ""; City.Text = ""; string fullName = EmployeesList.SelectedItem.ToString(); CacheManager cm = CacheFactory.GetCacheManager(); EmployeeDetails ed = (EmployeeDetails) cm.GetData(fullName); if (ed == null) { ed = GetEmployeeDetails(fullName); if (ed != null) { ShowEmployeeDetails(ed); cm.Add(ed.FullName,ed); } else { MessageBox.Show("Employee details could not be found!"); } } else { ShowEmployeeDetails(ed); }
}
The code is purely for demonstrating the caching abilities. The caching ability is simply demonstrated in the click event of GetDetails() The GetData() function of the CacheManager instance gets the cached value. In this case I am using the employees’ full name as the key for storing and retrieving items to and from the cache.
If the GetData() returns null then we are assuming that the details of the selected employee is not available in the cache and hence proceeding towards getting the data from the database and then storing the same in the cache for future use. If data is available in the cache then we are using the data thus saving a round trip to the database.
Conclusion
Part one started out by exploring what an application block is and why they are important for developers. It then provided an overview of three of the application blocks that are available in the new enterprise library. In this the second part I provided an overview of the remaining four application blocks. For each block we built a simplistic example to help understand what the block provides. Since the code for the enterprise library and all the samples built in this article are available for download, I would encourage you to explore them further, extend them and share your thoughts with the community.

