PIAB Custom Handler Not Intercepting

Topics: Policy Injection Application Block
Jul 23, 2007 at 7:36 PM
Hello,

I'm new to AOP and I'm having a hard time wrapping my brain around developing a custom handler. I'm not trying to create a whole new handler as found here: http://www.devx.com/dotnet/Article/34592.

I just want to create a handler that uses the built-in Custom Handler.

I have a very simple form:

namespace PIABTest
{
public partial class TestForm : Form
{
public TestForm()
{
InitializeComponent();
}

private void uxAddTest_Click(object sender, EventArgs e)
{
TestData testData = new TestData();
testData.AddTest(uxNameIn.Text);
}
}
}

Which calls a very simple middle-tier object:

namespace PIABTest.BusinessLogic
{
class TestData : MarshalByRefObject
{
private int id;
private string name;

public TestData()
{
id = 0;
name = "";
}

public int AddTest(string name)
{
this.name = name;

return id;
}
}
}

With the absolute most plain-jane call handler that I'm trying to put in the middle

using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
using Microsoft.Practices.EnterpriseLibrary.PolicyInjection;
using Microsoft.Practices.EnterpriseLibrary.PolicyInjection.Configuration;

namespace PIABTest
{
ConfigurationElementType(typeof(CustomCallHandlerData))
public class TestDataCallHandler : ICallHandler
{
public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
{
IMethodReturn msg = getNext()(input, getNext);

return msg;
}
}
}

and the PIAB part of my app.config is:
<policyInjection>
<policies>
<add name="Test Data Policy">
<matchingRules>
<add type="Microsoft.Practices.EnterpriseLibrary.PolicyInjection.MatchingRules.NamespaceMatchingRule, Microsoft.Practices.EnterpriseLibrary.PolicyInjection, Version=3.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
name="Namespace Matching Rule">
<matches>
<add match="PIABTest.BusinessLogic" ignoreCase="false" />
</matches>
</add>
</matchingRules>
<handlers>
<add type="PIABTest.TestDataCallHandler, PIABTest, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="TestData Handler" />
</handlers>
</add>
</policies>
</policyInjection>

I'm putting a breakpoint at TestDataCallHandler .Invoke but it's never hit. I'm obviously overlooking something abovious but I don't know what it is. I was happy that my TestDataCallHandler got recognized at all by the config editor as my first attempt didn't even get that.

Sorry for the baseness of my question but I would appreciate any help.
Jul 23, 2007 at 9:05 PM
Hi,

You need to let the policy engine do the creation for you, so it can hook the handlers, or do the wiring by yourself. Just doing "new TestData()" will not be enough, you need to do something like "PolicyInjection.Create<TestData>()".

Fernando
Jul 24, 2007 at 1:48 AM
D'oh! I knew it had to be something easy. Thank you very much.

However, now I'm getting an error at:
TestData testData = PolicyInjection.Create<TestData>();
stating "Constructor on type 'PIABTest.TestDataCallHandler' not found." even after I put in an explicit constructor. I looked back through the docs and it doesn't look like you need a constructor. What could be causing this?
Jul 24, 2007 at 2:06 AM
Hi,

Custom handlers are required to have a public constructor with a single NameValueCollection parameter.

Regards,
Fernando
Jul 24, 2007 at 5:47 PM
Hello,

Thanks loads, Fernando. It's all working great now. I feel like a tool but I'm happy it's working.

Sincerely,

nautonnier
Jul 25, 2007 at 9:55 PM
One more quick question, I was reordering my prototype and I put the callhandler and related classes in a seperate project. I went to edit the config file so that the Type on the custom handler was now pointing to the correct assembly. I clicked on the ellipsis, clicked on "Load an Assembly..." and found the assembly (I built the new project first) but it said the assembly didn't contain any types that implemented or inherited from ICallHandler. However, I edited the app.config file manually with the new namespace and type and it worked fine. What needs to be in the assembly for the edit configuration tool to recognize the type that implements ICallHandler?

TIA,

nautonnier
Jul 25, 2007 at 11:22 PM
Hi,

Make sure the custom call handler type has the ConfigurationElementType attribute. Runtime will work without it since v3, but the design time tool will filter the type out if the attribute is absent. This isn't related to the project reorganization though.

Fernando


nautonnier wrote:
One more quick question, I was reordering my prototype and I put the callhandler and related classes in a seperate project. I went to edit the config file so that the Type on the custom handler was now pointing to the correct assembly. I clicked on the ellipsis, clicked on "Load an Assembly..." and found the assembly (I built the new project first) but it said the assembly didn't contain any types that implemented or inherited from ICallHandler. However, I edited the app.config file manually with the new namespace and type and it worked fine. What needs to be in the assembly for the edit configuration tool to recognize the type that implements ICallHandler?

TIA,

nautonnier

Jul 28, 2007 at 1:09 AM
Hi Fernando,

I have this attribute on the class:
ConfigurationElementType(typeof(CustomCallHandlerData))

with this using at the top:
using Microsoft.Practices.EnterpriseLibrary.PolicyInjection.Configuration;

that has been there since before I had my original problem. Any ideas?

-nautonnier
Jul 30, 2007 at 3:55 PM
Hi,

The only reasonable explanation I can think of now for this is that you're referencing one set of assemblies when you build your library but you're using the tool matching a different set of assemblies.

I just tried with a minimal library and it worked just fine when the assemblies matched but it didn't when they didn't match.

namespace ClassLibrary3
{
ConfigurationElementType(typeof(CustomCallHandlerData))
public class MyHandler : ICallHandler
{
#region ICallHandler Members

public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
{
throw new Exception("The method or operation is not implemented.");
}

#endregion
}
}

Regards,
Fernando
Aug 29, 2007 at 8:24 AM
Hi,

I tried to create simple sample according your post but I have problems in this line:
<add type="PIABTest.TestDataCallHandler, PIABTest, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="TestData Handler" />

so I changed it into:
<add type="PIABTest.TestDataCallHandler, PIABTest />

but now I have this kind of error: The type 'PIABTest.TestDataCallHandler, PIABTest' cannot be resolved. Please verify the spelling is correct or that the full type name is provided.

Does anyone know where is my mistake?
thank you
Aug 29, 2007 at 12:30 PM
Hi,

What kind of problem do you have with <add type="PIABTest.TestDataCallHandler, PIABTest, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="TestData Handler" />?

Fernando
Aug 29, 2007 at 1:52 PM
Somehow I solved this.

I have only this for type

type="PIABTest.TestDataCallHandler, PIABTest"

Regards
Milan
Aug 29, 2007 at 3:15 PM
Keep in mind that the configuration tool will use the fully qualified name when configuring types, so knowing why PIABTest.TestDataCallHandler, PIABTest, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null didn't work in the first place will probably save you from some grief in the (near?) future...

Fernando