Wednesday 19 March 2014

Microsoft Enterprise Library



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

http://www.4guysfromrolla.com/images/el.perf.gifIn 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.
http://www.4guysfromrolla.com/images/el.gui.gifTo 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.
When I first looked at the original Logging Application Block, I nearly dismissed it as too much effort. I’m glad I persisted. Due to its automated setup and simplified configuration, the Logging and Instrumentation Application Block is far simpler to start working with and use in a real life project.

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

A LogEntry 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”:
http://www.codeproject.com/images/minus.gifCollapse | 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 the LogEntry;
  • 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 a LogEntry and to 1 for a LogEntry implicitly created by Logger.Write);
  • Severity - indicates the severity of the Log Entry, e.g., Information, Warning, Error etc.
  • Title - a summary of the LogEntry.Message.
Another overload takes a 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 a LogEntry 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:
http://www.codeproject.com/images/minus.gifCollapse | 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”:
http://www.codeproject.com/images/minus.gifCollapse | 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 a LogEntry 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.
You can always write your own Custom Log Sink as well.

Formatters

To persist a LogEntry, 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:
http://www.codeproject.com/images/minus.gif

2 comments: