We've been looking for some standard components in my group at work. The main issues were logging, data access, and centralized configuration. We'd kicked the tires on the Enterprise Library a bit, but our reaction was the standard "Gee, it looks complicated. Probably more trouble than it's worth." Then within one week, we got a barrage of EntLib information: a presentation by Scott Mitchell at the local San Diego .NET user group, presentations by Tom Hollander and Blake Dong (Avenade) at the Microsoft San Diego Architect Council, and an onsite Q & A with Tom Hollander. It all made sense: this is exactly what we were looking for, and it might be worth a second look if you'd decided to pass on it, too.
Enterprise Library is for enterprise development
Steve Smith summed that up pretty well here. A lot of people have complained that it's too complex, and it probably is overkill for smaller or standalone applications. The source code (included) has over 1300 files. The previous application blocks were geared towards simplifying and standardizing small discrete application aspects (e.g. data access block was basically a helper class, hence the name SqlHelper), and were pretty simple to use. The Enterprise Library has traded some of that simplicity for the benefits of a configuration driven plugin system that makes the .NET Framework feel like a business development framework.
It's a tradeoff: You put up with a few things:
- A nominal learning curve (assisted by the quickstart code samples)
- A minor performance penalty (designed to be under 5% in most cases, and your application may actually run faster if you take advantage of things like caching and async logging).
In exchange you get a few things that matter to bigger development shops:
- Simplified configuration
- Application consistency
- Futureproofing through plugin architecture
- A head start on many of the components of robust applications ("streamlining of common use cases" is the official term)
The Enterprise Library is a collection of seven blocks, six of which are optional. All of them require the Configuration block, which controls how they all work and work together. You can replace any of them with a plugin that implements the correct interfaces and is associated in the config file. Here's a quick runthrough on the highlights of each of the blocks. The config tool is big enough that I gave it its own list.
The Seven Blocks and the Config Tool
- XML driven application configuration, similar to .NET configuration, but adds a lot of features targeted at enterprise development
- Read / Write - Can update config file settings from code
- Security built in - supports encryption. Supporting encryption at this level helps with the chicken and egg issues of wanting to secure your configuration information, but needing to configure the security somewhere.
- Extensibility / flexibility - Provider model controlled in configuration allows you to customize EntLib with plugins, simplifying and reducing the risk of customizing EntLib to work the way your company works.
- Configuration Tool is included to simplify setup and maintenance. Config is XML and can be manually edited, but Config Tool makes this a lot easier.
- Updates trigger events in client applications. Configuration updates are different form web.config, which just kills the app domain. Entlib Config changes notify the application via an event. Application decides if it wants to reload configuration.
- Due to caching of configuration, you should always retrieve config values from block rather than holding onto them separately - can get out of sync.
- Can set in code or in machine.config if file based config doesn't fit your requirements
- Don't have to use Config Tool if you prefer hacking the XML
- Design classes map EntLib runtime classes to display, add wizards, etc.
- Design time classes depend on runtime classes, but never the reverse (don't need to deploy the design classes or Config Tool).
- Provider Model - Uses intermediate DLL's so there is no binary dependency between a class and the providers that feed it. Mapping of plugins is done in metaconfiguration.
- Design class pattern allows you to add support your own custom blocks or extensions to existing blocks to the Config Tool
- Symmetric encryption only (asymmetric key management is more difficult, processing is generally slower)
- Hashing and salting supported
- Very simple to use - only 4 methods (CreateHash, CompareHash, EncryptSymmetric, DecryptSymmetric).
- DPAPI support. DPAPI, the Data Protection API, provides operating system level support for symmetric encryption of secure information. DPAPI key can be associated with machine or user.
- Abstracts encryption specifics from usage - developer doesn't specify key or algorithm. One reason this is good - crypto is hard, and it's good to let a developer use it without guessing on crypto algorithm usage.
- Abstracts database technology (SQL Server, Oracle, etc. - can use
providers to support other data sources)
- May simplify database portability, but since databases support different technologies, this is not simple and isn't really the goal here.
- Real goal is to simplify developer portability - makes it easier for developers to move between applications and teams using different databases. Since I work at a company that runs just about all of the major database technologies (SQL Server, Oracle, DB2, Sybase, Informix, probably several I'm forgetting), this sounds nice.
- Helps ensure effective connection management
- Uses factory pattern. This is a change from the previous Data Access Application Block, and it trades simplicity for flexibility. One major benefit of this type of pattern is that it integrates smoothly with the Config block, so the connection string and other specifics of data access configuration are transparent to each specific usage
- This is a Data Access Layer, not a Business Logic / Object Relational Mapper kind of thing. It doesn't generate any classes and doesn't know anything about the tables it's talking to. This is a conceptual issue I've had to explain several times, so I figured it's worth spelling out. You build your Business Logic Layer (BLL) on top of this layer, and it handles communications with your data sources.
- Handles Authentication, Authorization, Roles, and Profiles
- Can use Facades to call into legacy security systems
- Configuration driven, so logging is routed at runtime
- Distribution strategy
- MSMQ supported as a sink and / or a distribution strategy
- MSMQ distributor processor - separate Windows service which processes logging messages in MSMQ, can run on another computer
- Logging by default requires WMI and Event Log permissions. Can recompile with a compiler define that removes instrumentation; next version will alow disabling the EIF in configuration
- Contextual trace - see Mitch's great explanation of contextual logging in the EIF. Context flows through the call stack, making the information much more valuable.
- V2 may allow one log entry to have a collection of categories which adds a lot more flexibility
- Facilitates consistent exception handling through an application or enterprise
- Prevents exposing sensitive data (such as database connection specifics returned in an exception message)
- Configuration driven exception policies allow changing exception handling policy for different user defined exception categories at runtime via configuration changes
- Available actions: Swallow, Bubble, Rethrow
- Support for "Backing Store" in either database or isolated storage (file) - allows for occasionally connected use
- Differs from ASP.NET cache in that it doesn't require web DLL's, is designed for thread safety in all application types, and supports backing store
- Doesn't support distributed Read / Write (webfarm, for instance)
Some other random tidbits
- There have been 100,000 downloads of the EntLib since January.
- Some overlap with ASP.NET (profile, cache), but simplifies library code. Can use Facade providers in ASP.NET to leverage base functionality if desired.
- Main patterns - Factory, Provider, Strategy
- History - Avenade Connected Architecture (ACA.NET) - Avenade was formed by Microsoft and Accenture. They were developing their own system for use in their projects which paralleled work in progress by the Microsoft Patterns and Practices Group, so they merged these together. Enterprise Library is pretty much a version 3.0 product due to its roots as the ACA.NET. Avenade continues to extend the ACA.
- Can copy Updater Block design DLL's to EntLib bin, and Updater Block will show up in Config Tool
- Heavily cached, so slow start but <5% performance penalty
Extending EntLib (see Blake Dong's PPT)
- Gray box - write custom providers
- Don't inherit from internal abstract classes if possible, stick with interfaces so upgrades don't cause you trouble
- Minimize coupling between brovider and blocks
- Use Enum to wrap categories (log categories, for instance) - allows strong typing, compile time typo check
- Since some of the logic has been moved into configuration file, can be a little tougher to debug. For instance, a log category of "DEGUB" wouldn't cause a config or compile time error, but log entry would never be written since no "DEGUB" category exists.
- Can use Facade Pattern (wrapper) to future proof
- Company.Name.Caching wrapps Caching block, for instance
- Can add Logging, AOP type stuff to wrappers
- Upgrade t new version of EntLib by updating the version number reference to the wrapper instead of EntLib config files everywhere
- ACA includes a pretty cool Attribute based Aspece Oriented Programming (AOP) system. Post-build step drives codegen which configures EntLib services.
Microsoft San Diego Architect Council
EntLib Overview- Tom Hollander, Microsoft - PPT - http://www.socalmsft.com/Council200505/EntLib%20Overview%20-%20Socal.ppt
Adopting Entlib - Blake Dong, Avenade - PPT - http://www.socalmsft.com/Council200505/SoCal%20Architect%20Forum%20-%20EntLib%20v3.ppt
Extending EntLib- Tom Hollander, Microsoft - PPT - http://www.socalmsft.com/Council200505/Extending%20EntLib%20-%20Socal.ppt
San Diego .NET User Group
Examining the Microsoft Enterprise Library - Scott Mitchell - Zip - http://datawebcontrols.com/classes/EntLib.zip
Installation tips / tricks
Install build 1473 and Memory Leak patch from the GotDotNet site.
Immediately after installing Enterprise Library, you MUST install the instrumentation and performance counters.
start\All Programs\Microsoft p&p\Enterprise Library\Install Services
This will execute installutil on each of the assemblies and register the performance counters. I would hope that in the next version of the installer, this option will be automatically executed after the solution is compiled. (via http://blog.hishambaz.com/archive/2005/02/02/240.aspx)