Configuring a Exception Policy using Interception

Topics: Exception Handling Application Block, Policy Injection Application Block
Jul 8, 2010 at 9:36 AM
Edited Jul 8, 2010 at 3:04 PM
Hello, I have defined a Exception policy and I want to configure my container to use it. I have read that is possible to do it through Policy Injection but now is better to do it using Interception. I have tried this: private void InitializeContainer() { container = new UnityContainer(); container.AddNewExtension<Interception>(); container.RegisterType<BusinessLogic.BankAccount>( new InterceptionBehavior<PolicyInjectionBehavior>(), new Interceptor<TransparentProxyInterceptor>()); container.AddNewExtension<EnterpriseLibraryCoreExtension>(); ExceptionPolicyImpl myPolicy = container.Resolve<ExceptionPolicyImpl>("ExceptionPolicy"); container.Configure<Interception>() .AddPolicy("MyPolicy") .AddMatchingRule<TypeMatchingRule>( new InjectionConstructor( new InjectionParameter(typeof(MyClass)))) .AddCallHandler<AuthorizationCallHandler>(" ExceptionPolicy ", new ContainerControlledLifetimeManager()); } and in the .config file I have: <configSections> <section name="loggingConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.LoggingSettings, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="true" /> <section name="exceptionHandling" type="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Configuration.ExceptionHandlingSettings, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="true" /> </configSections> <loggingConfiguration name="" tracingEnabled="true" defaultCategory="General"> <listeners> <add name="Event Log Listener" type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.FormattedEventLogTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.FormattedEventLogTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" source="Enterprise Library Logging" formatter="Text Formatter" log="" machineName="." traceOutputOptions="Timestamp, Callstack" /> </listeners> <formatters> <add type="Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.TextFormatter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" template="Timestamp: {timestamp}{newline} Message: {message}{newline} Category: {category}{newline} Priority: {priority}{newline} EventId: {eventid}{newline} Severity: {severity}{newline} Title:{title}{newline} Machine: {localMachine}{newline} App Domain: {localAppDomain}{newline} ProcessId: {localProcessId}{newline} Process Name: {localProcessName}{newline} Thread Name: {threadName}{newline} Win32 ThreadId:{win32ThreadId}{newline} Extended Properties: {dictionary({key} - {value}{newline})}" name="Text Formatter" /> </formatters> <categorySources> <add switchValue="All" name="General"> <listeners> <add name="Event Log Listener" /> </listeners> </add> </categorySources> <specialSources> <allEvents switchValue="All" name="All Events" /> <notProcessed switchValue="All" name="Unprocessed Category" /> <errors switchValue="All" name="Logging Errors & Warnings"> <listeners> <add name="Event Log Listener" /> </listeners> </errors> </specialSources> </loggingConfiguration> <exceptionHandling> <exceptionPolicies> <add name="ExceptionPolicy"> <exceptionTypes> <add name="All Exceptions" type="System.Exception, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" postHandlingAction="ThrowNewException"> <exceptionHandlers> <add name="Logging Exception Handler" type="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Logging.LoggingExceptionHandler, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" logCategory="General" eventId="100" severity="Error" title="Enterprise Library Exception Handling" formatterType="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.TextExceptionFormatter, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling" priority="0" /> </exceptionHandlers> </add> </exceptionTypes> </add> </exceptionPolicies> </exceptionHandling> But it didn´t work, Does anyone know what I´m doing bad? Thanks in advance
Jul 9, 2010 at 2:39 AM
Edited Jul 9, 2010 at 2:40 AM

Ok, here are the things that need to be corrected:

1.  Add first the EntepriseLibraryCoreExtension before any other extensions, in this case, before the Interception extension.

2.  Next, make sure you configured the TypeMatchingRule correctly.  In your case, you registered the BankAccount class but specified typeof(MyClass) in your TypeMatchingRule.  If you want to intercept the BankAccount class, you should specify typeof(BankAccount).

3.  You added an AuthorizationCallHandler but you don't have an Authorization Call Handler in your config.  When adding a call handler, you can either specify an instance which is resolved from the config or if you're creating a new one, you need to specify the values for constructing a new one.  In the case of an AuthorizationCallHandler, its constructor needs an IAuthorizationProvider parameter, a string parameter for the operationName, and an integer parameter for the order.  Thus, you must have an Authorization Provider defined in your config.  Supposing you add an Authorization Provider in your config named "Auth Provider", here's how your code should look like:

container = new UnityContainer();
container.AddNewExtension<EnterpriseLibraryCoreExtension>;
container.AddNewExtension<Interception>; 
container.RegisterType<BankAccount>(new InterceptionBehavior<PolicyInjectionBehavior>(), new Interceptor<TransparentProxyInterceptor>()); 

ExceptionPolicyImpl myPolicy = container.Resolve("ExceptionPolicy");
IAuthorizationProvider authProvider = container.Resolve("Auth Provider");
container.Configure()
            .AddPolicy("MyPolicy")
            .AddMatchingRule<TypeMatchingRule>(
                 new InjectionConstructor(new InjectionParameter(typeof(BankAccount)))) //assuming you want to intercept instances of the BankAccount class
            .AddCallHandler<AuthorizationCallHandler>(new ContainerControlledLifetimeManager(),
                 new InjectionConstructor(authProvider, "Deposit", 1)); //assuming you want to intercept the Deposit method of the BankAccount class

I think your original intention was to handle exception as a result of authorization exception, am I right?  If that's the case, it won't be possible configuring it using a single policy since if the authorization fails, the AuthorizationCallHandler it returns an UnauthorizedAccessException and prevents the succeeding handlers to execute.

Let me know if anything is unclear.

 

Sarah Urmeneta
Global Technology & Solutions
Avande, Inc.
entlib.support@avanade.com