Goals for Enterprise Library
Enterprise Library is a collection of application blocks intended for use by developers who build complex, enterprise-level applications.Enterprise Library is used when building applications that are typically to be deployed widely and to interoperate with other applications and systems. In addition, they generally have strict security, reliability, and performance requirements.
The Microsoft Enterprise Library
offers reusable software components to assist with building .NET applications.
Learn how to contribute to one or more of its projects.
I was introduced to the Microsoft
Application Blocks around the time of .NET version 1.1 with the data
application block. It does the heavy lifting for you, with all code written
according to Microsoft .NET recommendations, and it greatly simplifies
interacting with data backend (SQL Server in my case).
Since its inception, it has evolved into
the Microsoft Enterprise Library, which includes more features
on top of data access. This tour of the library's offerings focuses on recent
changes that allow you to contribute to its continuing evolution. I'll begin
with an overview of what comprises the Microsoft Enterprise Library and why you
should care about it.
foundation
The main goal of the Microsoft
Enterprise Library is to address common software needs. It meets this goal by
offering reusable software components to assist with building .NET
applications.
The library is comprised of eight
application blocks:
- Data Access simplifies working with an underlining database while providing methods for performing common tasks like calling stored procedures.
- Exception Handling provides a framework for centralizing exception handling, making it easier to manage exceptions. This application block provides implementations for handling standard exceptions and for creating custom variations.
- Logging provides everything necessary to create log entries in various locations. Like the other application blocks, it allows you to centralize the functionality and thus spend your time coding application functionality as opposed to standard, repeatable operations like logging.
- Policy Injection assists with implementing Aspect Oriented Programming techniques within your code. This is achieved by intercepting method calls and invoking handlers before and after those methods based on configuration information.
- Semantic Logging facilitates using strongly-typed logging (aka semantic) within your application. This provides a more consistent and standard approach to logging, which is beneficial when processing the log data.
- Transient Fault Handling: Code-named Topaz, it can be used to add support for handling transient faults to your code. These type of faults occur infrequently and often disappear after a few retries. A good example is network issues hampering connecting to a web service.
- Unity provides a dependency injection container to be used with your code.
- Validation provides validation routines for common application functions. This includes user interface adapters for ASP.NET controls.
An
Overview of the Enterprise Library
The previous application blocks created by the Patterns and Practices Group were designed independently of one another, meaning that each application block had its own code for accomplishing tasks common to all application blocks. For example, both the Data Access Application Block and the Exception Management Application Block can read data from the Web.config or App.config configuration files to determine their behavior. Furthermore, since each application block was developed separately from the other, the design goals were not necessarily unified. For example, the Exception Management Application Block (EMAB) was designed to provide an extensible interface to any medium for recording exception information. By default, the EMAB recorded exception information in the Event Log, but a developer could easily modify the EMAB to record exception information in a custom database table instead. The Data Access Application Block, however, was initially designed to only work with a specific data provider - Microsoft SQL Server - and did not provide a mechanism for specifying a different data provider (such as Oracle, Access, DB2, or other data stores).
The Enterprise
Library reconciles the rift between the various application blocks,
providing a more unified collection of seven different application blocks. From
the Enterprise Library home page, the seven application blocks are:
- Caching Application Block - this application block allows developers to incorporate a local cache in their applications.
- Configuration Application Block - this application block allows applications to read and write configuration information.
- Data Access Application Block - this application block allows developers to incorporate standard database functionality in their applications. (See Working with the Enterprise Library's Data Access Application Block for more information on using the DAAB!)
- Cryptography Application Block - this application block allows developers to include encryption and hashing functionality in their applications.
- Exception Handling Application Block - this application block allows developers and policy makers to create a consistent strategy for processing exceptions that occur throughout the architectural layers of enterprise applications.
- Logging and Instrumentation Application Block - this application block allows developers to incorporate standard logging and instrumentation functionality in their applications.
- Security Application Block - this application block allows developers to incorporate security functionality in their applications. Applications can use the application block in a variety of situations, such as authenticating and authorizing users against a database, retrieving role and profile information, and caching user profile information.
By combining the application blocks
into a single Enterprise Library, the applications blocks provide a higher
degree of consistency. Each of the application blocks uses similar design
patterns and share similar deployment and configuration requirements. Do keep
in mind that using the Enterprise Library in an application does not
require that all seven application blocks be used. You can pick and choose the
application blocks from the Enterprise Library that are pertinent to your
particular application's needs.
The Enterprise Library illustrates
Microsoft's recommended practices in not only the actual code of the
application blocks, but also in testing and operations. Each application block
provides numerous unit tests that can be run to verify the code's correctness,
and to ensure correctness when extending the code to meet your company's custom
needs. (For more on unit testing be sure to read Test Driven
Development Using NUnit in C#.) Additionally, the application blocks use
instrumentation through performance counters, Event Log entries, and WMI events
to enable administrators to monitor the health of an application and diagnose
problems as they arise. For example, when working with the Data Access
Application Block in the Enterprise Library, a plethora of performance counter
metrics are maintained, such as number of connections opened per second, and
average command execution time.
As with the previous application
blocks, the Enterprise Library's application blocks maintain their information
in the XML-formatted Web.config or App.config files (depending on whether you are integrating the
Enterprise Library into a Web application or desktop application). Previously,
the only way to modify the application block settings was to fiddle with the
XML settings by hand. The Enterprise Library, however, introduces a GUI tool
for maintaining settings information, which we'll examine shortly.
Enterprise Library
In order to get rolling with the Enterprise Library you'll first need to download the library from Microsoft's site. The download is a near 9 MB file, which includes the complete Enterprise Library application block source code, Quick Start examples, off-line documentation, the GUI tool, and other goodies. (One major annoyance is that in order to download the Enterprise Library you have to register with Microsoft. Boo.) Once you download the Enterprise Library, go ahead and run the downloaded file, which will step you through an installation process. During this installation process you can specify what application blocks to install, if you only want to install a subset of the seven. Upon completion of the installation, the pertinent files should be in the \Program Files\Microsoft Enterprise Library folder.
One step the installation
process seems to not do is create the Enterprise Library-specific performance
counters. I needed to do this step manually by going to the Start Menu -->
Programs --> Microsoft Patterns and Practices --> Enterprise Library
--> Install Services. The Install Services batch file ran completed the necessary
performance counters. Once these performance counters were created, when going
to the Performance monitor through Administrative Tools there were six new
items in the Performance Object drop-down list, as shown in the screenshot to
the right. For more information on instrumentation, including how to configure
the Enterprise Library to not use instrumentation, refer to Instrumentation
in Enterprise Library.
Working
with the Data Access Application Block
The remainder of this article looks at how to create a simple ASP.NET page that utilizes the Enterprise Library's Data Access Application Block to bind SQL Server database data to a DataGrid in an ASP.NET page. To get started, create a new ASP.NET Web application. In the Web application's WebForm1.aspx page, add a DataGrid from the Toolbox.
At this point, we need to indicate
that we want to use the Enterprise Library in our project. To accomplish this,
add the Microsoft.Practices.EnterpriseLibrary.Data and Microsoft.Practices.EnterpriseLibrary.Configuration assemblies to the project by right-clicking on the
References folder, choosing Add Reference, and then Browsing to the \Program Files\Microsoft Enterprise
Library\bin directory and adding the Microsoft.Practices.EnterpriseLibrary.Data.dll and Microsoft.Practices.EnterpriseLibrary.Configuration.dll files. Next, in the code-behind class, add at the top the
following two Imports statements:
Imports
Microsoft.Practices.EnterpriseLibrary.Data
Imports Microsoft.Practices.EnterpriseLibrary.Data.Sql |
Next, add the following code to the Page_Load event handler:
Dim db As Database = DatabaseFactory.CreateDatabase()
Dim sqlCommand As String = ... SQL query, like:
"SELECT * FROM TableName" ...
Dim dbCommandWrapper As DBCommandWrapper =
db.GetSqlStringCommandWrapper(sqlCommand)
DataGridID.DataSource
= db.ExecuteReader(dbCommandWrapper)
DataGridID.DataBind()
|
Note that the code to retrieve
database data does not provide any information about the data store to use.
That is, there's no connection string. No hint at if we are using SQL Server or
Oracle or some other data store. Rather, everything is referred to via an
abstract object. We have a Database object. We specify the command to execute and get back its
results via the ExecuteReader() method. (The complete Data Access Application Block API can
be found in the Enterprise Library documentation and studied in more depth
through the Quick Starts; a future 4Guys article will dive into the Data Access
Application Block in much greater detail.) All of the database specific
information is stored in a separate configuration file which can be created and
tweaked through the GUI tools provided by the Enterprise Library.
To load the GUI tool, go to the Start Menu --> Programs
--> Microsoft Patterns and Practices --> Enterprise Library -->
Enterprise Library Configuration. You can then open the configuration for your
Web application by going to the File menu, choosing Open Application, and
browsing to your Web application's Web.config file.
Once you have selected this file, the GUI tool will load in a tree node titled
Application. Right-click this and choose New --> Data Access Application
Block. This will add two children nodes: Configuration Application Block and
Data Access Application Block, as shown in the screenshot to the left.
The Configuration Application Block
settings will be saved to the Web.config file. The Data Access Application Block settings will be
saved to a separate file, dataConfiguration.config. To specify the database's connection string information,
expand the Sql Connection String node. For the connection string you can
specify an arbitrary number of parameters. These parameters are concatenated
together to form the complete connection string used to connect to the data
store. By default, the connection string contains three parameters: database,
server, and Integrated Security. You can add additional parameters if needed
(for example, rather than using Integrated Security, you might require a
specific User ID and Password parameter passed through the connection string).
Once you have the configuration
information specified, compile your Web application and visit the Web page
through a browser. If you configured everything correctly you should see the
database data specified by the SQL query used in the page's DataGrid.
Conclusion
The Enterprise Library is a more unified collection of application blocks from Microsoft's Patterns and Practices Group. The application blocks shipped with the Enterprise Library have been updated to utilize a shared common code base and similar semantics and syntax. The Enterprise Library is the next step in the evolution of the application blocks and provides an easy mechanism to accomplish common code tasks using libraries designed to showcase best practices.
This article provided a high-level
overview of the Enterprise Library and provided a quick peek into using the
Data Access Application Block. Future articles, such as Working with the
Enterprise Library's Data Access Application Block will delve into the
various application blocks in more detail.
By integrating the Enterprise Library
into new and existing applications, you can drastically reduce the amount of
code you need to write to accomplish common coding scenarios.
The Logging and Instrumentation Application Block provides a simple way for
your code to log information in a consistent manner across your managed
application. Powerful configuration files allow the filtering, routing and
formatting of those “Log Entries” to be determined at run time (rather than at
compile time). Log Entries can be generated as discrete events or as part of a
traced process.Some of the major improvements over the original stand-alone Logging Application Block are:
- Automated installation and compilation of the library on the developer's machine;
- The configuration file can be edited through a simple user interface (the Enterprise Library Configuration Console);
- No dependency on the EIF;
- The format of the data saved to a sink can be configured through the Enterprise Library Configuration Console rather than by providing XSLT files;
- The Database Sink is no longer SQL Server specific;
- New sinks such as the Email Sink and Flat File Sink.
The Basics
The Logging and Instrumentation Application Block makes use of four basic concepts to provide a logging framework: Log Entries, Tracers, Sinks and Formatters.Log Entries
ALogEntry
is the object
that you “write” when your application needs to log some information. For
instance, adding the following to your application would write a Log Entry containing
the message “Hello World”:
Collapse
| Copy Code
Logger.Write("Hello World");
It is as simple as that. OK, you do have to put in some using statements and your project must
reference the Enterprise Library... but the code can be as basic as that!The above code implicitly creates a
LogEntry
object with its Message
field set to “Hello World”. Overrides of the Logger.Write
method allow you to provide more information, such as:Category
- used to determine the routing of theLogEntry
;Priority
- used to filter Log Entries, only those above the “Minimum Priority” are processed (defaults to -1 which indicates that the Minimum Priority should be used);EventId
- a value you can use to further categorise Log Entries (defaults to 0 for aLogEntry
and to 1 for aLogEntry
implicitly created byLogger.Write
);Severity
- indicates the severity of the Log Entry, e.g.,Information
,Warning
,Error
etc.Title
- a summary of theLogEntry.Message
.
LogEntry
object, allowing you to set all these fields explicitly. A LogEntry
also has a number of additional
fields that are automatically populated with details of the system's state at
the time it was instantiated (e.g., machine name, timestamp, application domain
name, process ID etc.).Additional, context specific information can be added to a
LogEntry
through its ExtendedProperties
field. This takes a
reference to an IDictionary
object containing any additional name / value pairs you want to log. Included
with the Logging and Instrumentation Application Block are a number of “Extra
Information Providers”. These can be used to populate an IDictionary
object with some basic
information. For example, the ComPlusInformationProvider
will populate an IDictionary
object with details of the current COM+ context.Tracers
Whereas aLogEntry
allows
you to log a discrete event, a Tracer
object can be used to indicate that a LogEntry
is being written as part of a particular process (or execution path through the
application). For instance, you might use it to indicate that a LogEntry
has been written as part of a
“Create New Customer” process:
Collapse
| Copy Code
using (new Tracer("Create New Customer"))
{
Logger.Write("Hello World again");
}
When a Tracer
is
instantiated, you can either supply an activityId
(as the second parameter to the constructor) or allow a GUID to be generated
for you. A “Start Trace” Log Entry will then be written containing this
Activity ID. When the Tracer
object is disposed of, an “End Trace” Log Entry containing the elapsed time is
written. The using statement
in the above code ensures the Tracer
object is disposed of correctly.All Log Entries written between the using statement’s opening and closing brackets will automatically have a
TracerActivityId
entry added to their ExtendedProperties
(populated with the Tracer
object's Activity ID). This
includes Log Entries written from other methods, classes, or even assemblies.Tracer
objects can be
nested. Unless explicitly supplied with an activityId
,
an inner Tracer
object will
have the same Activity ID as its parent. Any Log Entries will be written with
their TracerActivityId
extended property set to the inner most Tracer
object's Activity ID. In the following code, the first LogEntry
is written with a TracerActivityId
set to “Outer
”, the second with the value set to
“Inner
”:
Collapse
| Copy Code
using (new Tracer("Outer most trace", "Outer"))
{
using (new Tracer("A nested trace"))
{
Logger.Write("Hello World inside");
}
using (new Tracer("Another nested trace", "Inner"))
{
Logger.Write("Hello World inside again");
}
}
A number of static methods on the Tracer
class allow you to discover information about the current and outermost (or
“Root”) Tracer
objects.Log Sinks
When aLogEntry
is
“written”, the Logging and Instrumentation Application Block routes it to one
or more Log Sinks. A Log Sink receives Log Entries and is responsible for
persisting them. The Logging and Instrumentation Application Block provides six
Log Sinks:- Event Log – writes to a Windows Event Log;
- Flat File – writes to a text file;
- Microsoft Message Queuing – writes to a message queue;
- E-mail – sends Log Entries via an SMTP server;
- Database –
executes a stored procedure for each
LogEntry
; - WMI Log – fires WMI events.
Formatters
To persist aLogEntry
,
the Log Sink uses a Formatter to convert the Log Entry's information into a
string. The Logging and Instrumentation Application Block provides a single
formatter, the TextFormatter
.The
TextFormatter
is
initialised with a template that dictates which properties of the LogEntry
are added to the output string.
For instance, a template like this:
Thanks a lot for that information. That was really Interesting post.
ReplyDeletethanks to share..
ReplyDelete