Title: Introducing the Policy Injection Application Block
1Introducing the Policy Injection Application
Block
2Agenda
- Enterprise Library 3.0 Introduction
- Policy Injection Motivation and Goals
- Policy Injection Application Block Architecture
- Call Handlers and Matching Rules
- Extending the PIAB
- Summary
3Enterprise Library 3.0 New Features At a Glance
- New application blocks
- Validation Application Block
- Policy Injection Application Block
- Improvements to existing application blocks
- Data Access Application Block
- Logging Application Block
- .NET Framework 3.0 integration
- Logging, Exception Handling and Validation
Application Blocks
- Configuration improvements
- Visual Studio-integrated configuration tool
- Environmental Overrides
- Manageable Configuration Source
- Automation
- Application Block Software Factory
- Strong Naming Guidance Package
4Enterprise Library 3.0 Application Blocks
5Agenda
- Enterprise Library 3.0 Introduction
- Policy Injection Motivations and Goals
- Policy Injection Application Block Architecture
- Matching Rules and Call Handlers
- Extending the PIAB
- Summary
6Context
- Applications include a mix of business logic and
cross cutting concerns - Cross cutting concerns include security, state
management and operational - Authorization, logging, caching, transaction
management, etc. - Both types of logic are necessary, but each have
unique characteristics - Business logic is highly contextual and often not
reusable - Cross cutting concerns are often applied
consistently across layers and applications
7Mixing Business and Cross-Cutting Concerns
- Traditionally, business logic and cross-cutting
concerns are mixed together in code - Even if a shared component or application block
is used, it is still generally called from code - This can lead to
- Code that is hard to read and maintain
- Duplicated code
- Inconsistent behavior
8Sample Method
Customer GetCustomerById(int id) if (id lt
0) throw new ArgumentException("Invalid Customer
Id") Customer customer HttpContext.Current.
Cache.Get(id.ToString()) as Customer if
(customer ! null) return customer
try Database db
DatabaseFactory.CreateDatabase("CRM")
using (IDataReader reader db.ExecuteReader("spGe
tCustomerById", id)) if
(reader.Read())
customer new Customer(id, reader.GetString(0),
reader.GetString(1))
HttpContext.Current.Cache.Add(id.ToString(),
customer, null, DateTime.Now.AddMinutes(1),
Cache.NoSlidingExpiration, CacheItemPriority.Norma
l, null) return customer
return null
catch (Exception ex) if
(ExceptionPolicy.HandleException(ex, "Data
Policy")) throw return null
9Policy Injection Application Block Goals
- Separate cross-cutting concerns from business
logic - Use interception and injection to apply policies
at runtime - Allow policies to be defined declaratively, using
configuration or attributes - At a coarse- or fine-grained level
- Make it easy to integrate Enterprise Library
application blocks into policies - Validation, Logging, Authorization, Exception
Handling, Caching, Performance Counters - Design for loose-coupling and extensibility
10Sample Method with Policy Injection
ValidationCallHandler CachingCallHandler(0, 1,
0) Tag("Data Access") Customer
GetCustomerById( RangeValidator(0,
RangeBoundaryType.Inclusive, 0,
RangeBoundaryType.Ignore) int id) Database
db DatabaseFactory.CreateDatabase("CRM")
using (IDataReader reader db.ExecuteReader("spGe
tCustomerById", id)) if
(reader.Read()) return new
Customer(id, reader.GetString(0),
reader.GetString(1))
11Agenda
- Enterprise Library 3.0 Introduction
- Policy Injection Motivation and Goals
- Policy Injection Application Block Architecture
- Call Handlers and Matching Rules
- Extending the PIAB
- Summary
12Policy Injection Application Block Basics
- Policy Injection Application Block provides a
factory for creating or wrapping policy-enabled
objects - If policies are defined in attributes or
configuration, a proxy is returned in lieu of the
real object - When calling policy-enabled members, a handler
pipeline is executed before and after the real
member is called - Each handler can access the data going in and out
of the call
13Policy Injection Application Block Basics
- Normally, each handler will implement a
cross-cutting concern before passing control to
the next handler (or the target) - A handler may also choose to abort the pipeline
if deemed appropriate
14Policies
- The definition of which handlers should execute
for which objects and methods is called a policy - There are two types of polices
- Configuration-based policies
- Attribute-based policies
15Configuration-based Policies
- A configuration-based policy consists of
- A set of matching rules
- A pipeline of handlers
- Matching rules are predicates that specify which
members the policy should apply to - For example, everything in the GlobalBank.Business
Logic namespace, or all members returning a
BankAccount - Multiple matching rules are ANDed together
- The handler pipeline specifies the ordered list
of handlers that will execute if the matching
rules pass - More than one policy may apply to any given
member - They will be applied in the order specified in
configuration
16Attribute-based Policies
- An attribute-based policy consists of a set of
call handlers applied directly to objects and
members using custom attributes - Matching rules are not used
- Attributes are discovered first on types, then on
members, and applied in order of discovery - Order of discovery of multiple attributes applied
on the same element cannot be guaranteed - Attribute-based policies are always applied
before configuration-based policies
CachingCallHandler(0, 1, 0) LogCallHandler(LogB
eforeCall true, LogAfterCall false,
BeforeMessage "About to call the
method") public int DoSomething(string input)
///
17Disabling Policies
- Both configuration- and attribute-based policies
can be disabled for a given type or member - Use the ApplyNoPolicies attribute to prevent
policies being applied - Useful for methods that are performance critical,
need no cross-cutting concerns or implement
concerns differently
18Interception and Injection
- In order for policies to execute when a method is
called - Configuration- or attribute-based policies must
apply to the member - The instance must be created or wrapped using the
PolicyInjection factory - The target object must be interceptable
- Requirements depend on the chosen injection
mechanism - Method must be called via the proxy returned from
the PolicyInjection.Create/Wrap methods, not
directly on the object
19Creating or wrapping objects
- Objects must be created or wrapped with the
PolicyInjection class for policies to apply - Even if no policies apply now, you may want to
create objects this way to allow policies to be
added in the future - Performance impact is very low if no policies
apply
MyClass1 object1 PolicyInjection.CreateltMyClassgt
() MyClass2 object2 PolicyInjection.CreateltMyCl
assgt(param1, param2) IMyInterface object3
PolicyInjection.CreateltMyClass3,
IMyInterfacegt() MyClass1 object4 new
MyClass() MyClass1 object4proxy
PolicyInjection.WrapltMyClass1gt(object4) IMyInter
face object5 new MyClass3() IMyInterface
object5proxy PolicyInjection.WrapltIMyInterfacegt(
object5)
20Interception Requirements
- The requirements for intercepting objects and
members depends on the chosen injection strategy - The PIAB ships with a Remoting Proxy injection
strategy - Can be replaced by alternative methods
- The Remoting Proxy Injection requires
- The class derive from MarshalByRefObject, or
- The class implement any interface, with
intercepted calls made through that interface
21Calling Policy Injected Members
- Calling policy injected members is no different
to calling any other member - The caller cant even tell if policies exist or
not - Policies do not alter the method signature
- Although they may alter the behavior
- Caller just calls a method and gets a return
result or exception - Caller doesnt know if result came from the
method or a handler
BankAccount account PolicyInjection.CreateltBankA
ccountgt(accountId) try account.Withdraw(am
ount) catch (Exception ex) // do
something
22Agenda
- Enterprise Library 3.0 Introduction
- Policy Injection Motivations and Goals
- Policy Injection Application Block Architecture
- Call Handlers and Matching Rules
- Extending the PIAB
- Summary
23Supplied Handlers
- PIAB ships with six handlers
- Validation Handler
- Logging Handler
- Authorization Handler
- Exception Handling Handler
- Caching Handler
- Performance Counter Handler
- Most are shims over other Enterprise Library
application blocks
24Validation Handler
- Validates parameters to a method, using the
Validation Application Block - Validation rules can be defined
- As rule sets defined on parameter types, using
either attributes or configuration - By applying validation attributes directly on the
method parameters - If validation fails, an ArgumentValidationExceptio
n is thrown, and the method is not called - Exception contains the ValidationResults from the
validation call
25Logging Handler
- Writes a log entry before and/or after the method
is called, using the Logging Application Block - Uses a TraceLogEntry which contains additional
properties related to the method call - Handler may be configured to log additional data,
including - Call Stack
- Parameter Values
- Return Value or Exception
- Call execution time
- Log Categories are configurable and may include
tokens such as method and type
26Authorization Handler
- Uses a Security Application Block Authorization
Provider to determine if the current user is
authorized to perform an operation - Current user is determined from the thread
principal - Handler is configured with
- The name of the Authorization Provider instance
to use - The name of the Operation, which can include
tokens such as type and method - If authorization fails, an UnauthorizedAccessExcep
tion is thrown, and the method is not called
27Exception Handling Handler
- Executes after a method is called
- Processes any exceptions thrown by the method
using the Exception Handling Application Block - Handler is configured with the name of the
Exception Policy to use - After processing, the handler will throw either
the original or the new exception back to the
caller, based on the exception policy definition - Exceptions may only be swallowed for void methods
28Caching Handler
- Uses the System.Web.Cache to cache method return
values, keyed off the method signature and input
parameters - Keys are generated using GetHashCode
- Handler is configured with a TimeSpan indicating
how long return values should be cached - Before the method is called, the handler checks
if a value is in the cache for the set of inputs - If so, the cached return value is returned,
instead of calling the method. - If not, the method is called and the return value
is cached for future use
29Performance Counter Handler
- Increments a number of performance counters that
provide useful metrics around use and performance - Handler can be configured to specify which
counters and instances to use - Available counters include
- Total number of times the method is called
- Rate of calls (per second)
- Average call duration
- Number of exceptions thrown
- Rate of exceptions thrown (per second)
30Supplied Matching Rules
- PIAB includes a number of matching rules that
test members against static metadata - Assembly Matching Rule
- Custom Attribute Matching Rule
- Member Name Matching Rule
- Method Signature Matching Rule
- Namespace Matching Rule
- Parameter Type Matching Rule
- Property Matching Rule
- Return Type Matching Rule
- Tag Attribute Matching Rule
- Type Matching Rule
31Effective Policy Viewer
- While the PIAB offers many benefits, separating
business code from cross cutting concerns can
also create confusion - Complete behavior cannot be determined only by
looking at code - To take away the mystery, pp provides the
Effective Policy Viewer - This application shows which policies and
handlers (configuration and attribute-based) will
apply to which members in which order - Tool can be downloaded from http//codeplex.com/en
tlib
32Agenda
- Enterprise Library 3.0 Introduction
- Policy Injection Goals
- Policy Injection Application Block Architecture
- Call Handlers and Matching Rules
- Extending the PIAB
- Summary
33Extensibility points
- The Policy Injection Application Block is
designed to be extended - Defined extensibility points are
- Matching Rules
- Handlers
- Injectors
- Other changes are possible by modifying source
code
34Building Custom Matching Rules
- Build a new class implementing IMatchingRule
- Create necessary constructors and fields for
configurable properties - Implement Matches
- bool Matches(MethodBase member)
- Build a runtime configuration class, if you want
strongly-typed configuration, or use
CustomMatchingRuleData - Add the ConfigurationElementType attribute to the
class, pointing to the runtime configuration class
35Building Custom Handlers
- Build a new class implementing ICallHandler
- Create necessary constructors and fields for
configurable properties - Implement Invoke
- IMethodReturn Invoke(IMethodInvocation input,
GetNextHandlerDelegate getNext) - Perform any pre-processing
- Call the next handler using getNext().Invoke(input
, getNext) - Perform any post-processing
- Return the desired return value or exception
- Build a runtime configuration class, if you want
strongly-typed configuration, or use
CustomCallHandlerData - Add the ConfigurationElementType attribute to the
class, pointing to the runtime configuration class
36Agenda
- Enterprise Library 3.0 Introduction
- Policy Injection Motivations and Goals
- Policy Injection Application Block Architecture
- Call Handlers and Matching Rules
- Extending the PIAB
- Summary
37Summary
- The Policy Injection Application Block is about
separating business logic from cross cutting
concerns - Cross cutting concerns are applied using
policies, comprising of matching rules and a
handler pipeline - Each handler can perform logic before or after a
method call - Policy-enabled objects are created with a factory
that returns a proxy wired up to the handler
pipeline - Used wisely, this application block can improve
clarity, maintainability and consistency of
applications
38Resources
- Download Enterprise Library and related resources
from - http//msdn.microsoft.com/practices
- Join the Enterprise Library Community at
- http//codeplex.com/entlib
- Share community extensions at
- http//codeplex.com/entlibcontrib
- Read blogs from the Enterprise Library team at
- http//msdn.microsoft.com/practices/Comm/EntLibBlo
gs
39(No Transcript)