how to use both custom handler and ValidationCallHandler in the same method by unity 2.0 container?

May 31, 2011 at 4:08 AM

For example,I want  to use customCallHandler and ValidationCallHandler  in the Deposit method,

and I instance the BankAccount by the following code ,but it always throw exception,so I want to know how to instance the class?

thank you!

 

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

      bankAccount = container.Resolve<BusinessLogic.BankAccount>();

 

public sealed class BankAccount : MarshalByRefObject
    {
 
        [customCallHandler("interception1")]
        [ValidationCallHandler()]
        public void Deposit([RangeValidator(typeof(Decimal), "0.0",
                     RangeBoundaryType.Exclusive, "0.0",
                     RangeBoundaryType.Ignore)] decimal depositAmount)
        {
            balance += depositAmount;
        }
            
    }

May 31, 2011 at 4:15 AM

by the way ,I use the following code instance the class,but it still didn't work.

 

  container = new UnityContainer();

            container
                    .AddNewExtension<Interception>()
                    .RegisterType<BusinessLogic.BankAccount>
                    (
                        new ContainerControlledLifetimeManager(),
                        new Interceptor(typeof(VirtualMethodInterceptor), "VMInterceptor"),
                        new InterceptionBehavior<PolicyInjectionBehavior>()
                     )
                    .Configure<Interception>()
                    .AddPolicy("MyValidation")
                    .AddMatchingRule(typeof(TagAttributeMatchingRule), new InjectionConstructor("Deposit"))
                    .AddCallHandler
                        (typeof(ValidationCallHandler), "VHandler",
                        new ContainerControlledLifetimeManager(),
                        new InjectionConstructor
                            ("RuleSet", SpecificationSource.Attributes)
                        );
            bankAccount = container.Resolve<BusinessLogic.BankAccount>();

May 31, 2011 at 8:09 AM

Hi,

From the first code you've posted to make the ValidationCallHandler() Attribute to work, the only thing you need to do is to make sure to add an extension of EnterpriseLibraryCoreExtension. This should look something like as follows;

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

            var bankAccount = container.Resolve<BankAccount>();

            bankAccount.Deposit(0);

While for your CustomCallHandler you would need first to create a Handler Attributes to make this work. Please refer to this section from the documentation - http://msdn.microsoft.com/en-us/library/ff660921(v=PandP.20).aspx.

Gino Terrado
Global Technologies and Solutions
Avanade, Inc.
entlib.support@avanade.com

 

May 31, 2011 at 8:20 AM

While if you would want to use the second approach you've posted. The code should look something like this;

IUnityContainer container = new UnityContainer();
            container.AddNewExtension<Interception>();
            container.AddNewExtension<EnterpriseLibraryCoreExtension>();

            container.RegisterType<BankAccount>(
                new Interceptor<TransparentProxyInterceptor>(),
                new InterceptionBehavior<PolicyInjectionBehavior>())
                .Configure<Interception>()
                .AddPolicy("TestMethodValidation")
                .AddMatchingRule(typeof(TagAttributeMatchingRule), new InjectionConstructor("TestTag"))
                .AddCallHandler(typeof(ValidationCallHandler), new InjectionConstructor("RuleSet", SpecificationSource.Attributes))
                .AddCallHandler(new MyCustomHandler())
                ;

And you need to add this Attribute in your Deposit method in the BankAccount class;

[Tag("TestTag")]

HTH.

Gino Terrado
Global Technologies and Solutions
Avanade, Inc.
entlib.support@avanade.com

 

May 31, 2011 at 8:27 AM

thank you ,

your code is works!

thank you very much !

Jun 28, 2013 at 7:03 PM
Edited Jun 28, 2013 at 7:08 PM
Thank you for the example. It really helped me understand how to use Unit with attribute validation.

I was looking at the Code Contracts .Net Extension (http://visualstudiogallery.msdn.microsoft.com/1ec7db13-3363-46c9-851f-1ce455f66970). We're not normally able to use 3rd party libraries due to FDA requiring they be validated.

I hope my code below can help others!

Here's my class:
using System;
using Microsoft.Practices.EnterpriseLibrary.Validation.PolicyInjection;
using Microsoft.Practices.EnterpriseLibrary.Validation.Validators;

namespace ValidationExperiment
{
    public class Class1 : MarshalByRefObject
    {
        [ValidationCallHandler]
        public void Method1(
            [NotNullValidator] [StringLengthValidator(3, 10)] string string1,
            [RangeValidator(typeof(int), "-14", RangeBoundaryType.Inclusive, "27", RangeBoundaryType.Exclusive)] int int1,
            [RangeValidator(typeof(decimal), "0.0", RangeBoundaryType.Exclusive, "0.0", RangeBoundaryType.Ignore)] decimal dec1)
        {
            // nothing to do here!
            //throw new NotImplementedException();
        }
    }
}
Here are my tests:
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration.Unity;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.InterceptionExtension;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using ValidationExperiment;

namespace Class1Tests
{
    [TestClass]
    public class Class1Tests
    {
        private IUnityContainer container;

        [TestMethod]
        [ExpectedException(typeof(Microsoft.Practices.EnterpriseLibrary.Validation.PolicyInjection.ArgumentValidationException))]
        public void Method1Test_Dec1Low()
        {
            var target = container.Resolve<Class1>();
            target.Method1("test", 1, -12342423423424);

            Assert.Fail("Exception was expected");
        }

        [TestMethod]
        [ExpectedException(typeof(Microsoft.Practices.EnterpriseLibrary.Validation.PolicyInjection.ArgumentValidationException))]
        public void Method1Test_Int1High()
        {
            var target = container.Resolve<Class1>();
            target.Method1("test", 10000, 1);

            Assert.Fail("Exception was expected");
        }

        [TestMethod]
        [ExpectedException(typeof(Microsoft.Practices.EnterpriseLibrary.Validation.PolicyInjection.ArgumentValidationException))]
        public void Method1Test_Int1Low()
        {
            var target = container.Resolve<Class1>();
            target.Method1("test", -10000, 1);

            Assert.Fail("Exception was expected");
        }

        [TestMethod]
        public void Method1Test_Pass()
        {
            var target = container.Resolve<Class1>();
            target.Method1("abc123", 1, 1);

            // no exception means it passed!
        }

        [TestMethod]
        [ExpectedException(typeof(Microsoft.Practices.EnterpriseLibrary.Validation.PolicyInjection.ArgumentValidationException))]
        public void Method1Test_String1Null()
        {
            var target = container.Resolve<Class1>();
            target.Method1(null, 1, 1);

            Assert.Fail("Exception was expected");
        }

        [TestMethod]
        [ExpectedException(typeof(Microsoft.Practices.EnterpriseLibrary.Validation.PolicyInjection.ArgumentValidationException))]
        public void Method1Test_String1TooLong()
        {
            var target = container.Resolve<Class1>();
            target.Method1("Way too long!", 1, 1);

            Assert.Fail("Exception was expected");
        }

        [TestMethod]
        [ExpectedException(typeof(Microsoft.Practices.EnterpriseLibrary.Validation.PolicyInjection.ArgumentValidationException))]
        public void Method1Test_String1TooShort()
        {
            var target = container.Resolve<Class1>();
            target.Method1("a", 1, 1);

            Assert.Fail("Exception was expected");
        }

        //Use TestInitialize to run code before running each test
        [TestInitialize]
        public void MyTestInitialize()
        {
            container = new UnityContainer();
            container.AddNewExtension<Interception>();
            container.AddNewExtension<EnterpriseLibraryCoreExtension>();
            container.RegisterType<Class1>(
                new InterceptionBehavior<PolicyInjectionBehavior>(),
                new Interceptor<TransparentProxyInterceptor>()
                );
        }
    }
}