VirtualMethodInterceptor does not work with EntLib DataAccessBlock.
description
<p>We want to be able to intercept method calls to the EntLib DAB's Database class. Specifically we want to intercept ExecuteReader, ExecuteNonQuery, etc, to create a CallHandler which logs the SQL which is being executed. Unfortunately we get this error when we try to use interception.</p>
<p> </p>
<p>Microsoft.Practices.Unity.ResolutionFailedException was unhandled</p>
<p> Message="Resolution of the dependency failed, type = \"Microsoft.Practices.EnterpriseLibrary.Data.Database\", name = \"Default\". Exception message is: The current build operation (build key Build Key[Microsoft.Practices.EnterpriseLibrary.Data.GenericDatabase, Default]) failed: The current build operation (build key Build Key[Microsoft.Practices.EnterpriseLibrary.Data.GenericDatabase, Default]) failed: Value cannot be null.\r\nParameter name: str (Strategy type DynamicMethodConstructorStrategy, index 0) (Strategy type BuildPlanStrategy, index 5)"</p>
<p> Source="Microsoft.Practices.Unity"</p>
<p> NameRequested="Default"</p>
<p> TypeRequested="Database"</p>
<p> StackTrace:</p>
<p> at Microsoft.Practices.Unity.UnityContainer.DoBuildUp(Type t, Object existing, String name)</p>
<p> at Microsoft.Practices.Unity.UnityContainer.DoBuildUp(Type t, String name)</p>
<p> at Microsoft.Practices.Unity.UnityContainer.Resolve(Type t, String name)</p>
<p> at Microsoft.Practices.Unity.UnityContainerBase.Resolve[T](String name)</p>
<p> at UnityScratch.Program.Main(String[] args) in C:\Users\mattdot\Documents\Visual Studio 2008\Projects\UnityScratch\UnityScratch\Program.cs:line 31</p>
<p> at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)</p>
<p> at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()</p>
<p> at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)</p>
<p> at System.Threading.ThreadHelper.ThreadStart()</p>
<p> InnerException: Microsoft.Practices.ObjectBuilder2.BuildFailedException</p>
<p> Message="The current build operation (build key Build Key[Microsoft.Practices.EnterpriseLibrary.Data.GenericDatabase, Default]) failed: The current build operation (build key Build Key[Microsoft.Practices.EnterpriseLibrary.Data.GenericDatabase, Default]) failed: Value cannot be null.\r\nParameter name: str (Strategy type DynamicMethodConstructorStrategy, index 0) (Strategy type BuildPlanStrategy, index 5)"</p>
<p> Source="Microsoft.Practices.ObjectBuilder2"</p>
<p> BuildKey="Build Key[Microsoft.Practices.EnterpriseLibrary.Data.GenericDatabase, Default]"</p>
<p> ExecutingStrategyIndex=5</p>
<p> ExecutingStrategyTypeName="BuildPlanStrategy"</p>
<p> StackTrace:</p>
<p> at Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext context)</p>
<p> at Microsoft.Practices.ObjectBuilder2.Builder.BuildUp(IReadWriteLocator locator, ILifetimeContainer lifetime, IPolicyList policies, IStrategyChain strategies, Object buildKey, Object existing)</p>
<p> at Microsoft.Practices.Unity.UnityContainer.DoBuildUp(Type t, Object existing, String name)</p>
<p> InnerException: Microsoft.Practices.ObjectBuilder2.BuildFailedException</p>
<p> Message="The current build operation (build key Build Key[Microsoft.Practices.EnterpriseLibrary.Data.GenericDatabase, Default]) failed: Value cannot be null.\r\nParameter name: str (Strategy type DynamicMethodConstructorStrategy, index 0)"</p>
<p> Source="Microsoft.Practices.ObjectBuilder2"</p>
<p> BuildKey="Build Key[Microsoft.Practices.EnterpriseLibrary.Data.GenericDatabase, Default]"</p>
<p> ExecutingStrategyIndex=0</p>
<p> ExecutingStrategyTypeName="DynamicMethodConstructorStrategy"</p>
<p> StackTrace:</p>
<p> at Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext context)</p>
<p> at Microsoft.Practices.ObjectBuilder2.DynamicMethodBuildPlanCreatorPolicy.CreatePlan(IBuilderContext context, Object buildKey)</p>
<p> at Microsoft.Practices.ObjectBuilder2.BuildPlanStrategy.PreBuildUp(IBuilderContext context)</p>
<p> at Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext context)</p>
<p> InnerException: System.ArgumentNullException</p>
<p> Message="Value cannot be null.\r\nParameter name: str"</p>
<p> Source="mscorlib"</p>
<p> ParamName="str"</p>
<p> StackTrace:</p>
<p> at System.Reflection.Emit.DynamicILGenerator.Emit(OpCode opcode, String str)</p>
<p> at Microsoft.Practices.ObjectBuilder2.DynamicMethodConstructorStrategy.PreBuildUp(IBuilderContext context)</p>
<p> at Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext context)</p>
<p> InnerException: </p>
<p> </p>
<p>Here is some sample code:</p>
<p> </p>
<p>using System;</p>
<p>using System.Collections.Generic;</p>
<p>using System.Linq;</p>
<p>using System.Text;</p>
<p>using Microsoft.Practices.Unity;</p>
<p>using Microsoft.Practices.EnterpriseLibrary.Data;</p>
<p>using System.Data;</p>
<p>using System.Data.Common;</p>
<p>using Microsoft.Practices.EnterpriseLibrary.Common.Configuration.Unity;</p>
<p>using Microsoft.Practices.EnterpriseLibrary.Data.Configuration.Unity;</p>
<p>using System.Diagnostics;</p>
<p>using Microsoft.Practices.Unity.InterceptionExtension;</p>
<p> </p>
<p>namespace UnityScratch</p>
<p>{</p>
<p> class Program</p>
<p> {</p>
<p> static void Main(string[] args)</p>
<p> {</p>
<p> IUnityContainer container = new UnityContainer();</p>
<p> container.AddNewExtension<EnterpriseLibraryCoreExtension>();</p>
<p> container.AddNewExtension<DataAccessBlockExtension>();</p>
<p> </p>
<p> container.AddNewExtension<Interception>();</p>
<p> container.Configure<Interception>()</p>
<p> .SetDefaultInterceptorFor<GenericDatabase>(new VirtualMethodInterceptor());</p>
<p> .AddPolicy("SQLTRACE")</p>
<p> .AddMatchingRule<ExecuteMatchingRule>()</p>
<p> .AddCallHandler<SqlLoggerCallHandler>();</p>
<p> </p>
<p> Database db = container.Resolve<Database>("Default");</p>
<p> DbCommand cmd = db.GetStoredProcCommand("getroles");</p>
<p> </p>
<p> db.AddInParameter(cmd, "p_Id", DbType.Int64, 1234);</p>
<p> </p>
<p> using (IDataReader reader = db.ExecuteReader(cmd))</p>
<p> {</p>
<p> while (reader.Read())</p>
<p> {</p>
<p> Debug.Print(reader.GetString(1));</p>
<p> }</p>
<p> }</p>
<p> }</p>
<p> }</p>
<p> </p>
<p> public class ExecuteMatchingRule : IMatchingRule</p>
<p> {</p>
<p> #region IMatchingRule Members</p>
<p> </p>
<p> public bool Matches(System.Reflection.MethodBase member)</p>
<p> {</p>
<p> return member.Name.StartsWith("Execute");</p>
<p> }</p>
<p> </p>
<p> #endregion</p>
<p> }</p>
<p> </p>
<p> </p>
<p> public class SqlLoggerCallHandler : ICallHandler</p>
<p> {</p>
<p> </p>
<p> #region ICallHandler Members</p>
<p> </p>
<p> public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)</p>
<p> {</p>
<p> IMethodReturn msg = getNext()(input, getNext);</p>
<p> </p>
<p> return msg;</p>
<p> }</p>
<p> </p>
<p> public int Order</p>
<p> {</p>
<p> get;</p>
<p> set;</p>
<p> }</p>
<p> </p>
<p> #endregion</p>
<p> }</p>
<p>}</p>