PolicyInjection and this

Topics: General discussion, Policy Injection Application Block
Jan 27, 2010 at 3:07 PM
Edited Jan 27, 2010 at 3:09 PM

Hi,

I recently encountered an issue with policy injection.

I have an interface ICalculator and a concrete implementation Calculator implementing the interface.

The interface declares a simple Add function decorated with [ValidationCallHandler] and some constraints on the 2 arguments (RangeValidator between 0 and 10)

The interface also declares a simple Add2 method with no attribute. But in the implementation Add2 will forward its call  to this.Add.

I was expecting to get an error in validation when going through the Add2 method, but nothing happens as if the internal this was not "policy injected".

Here is a snippet of the code:

public interface ICalculator {
	[ValidationCallHandler]
	int Add(
	[RangeValidator(0, RangeBoundaryType.Inclusive, 10, RangeBoundaryType.Inclusive)] int a, 
	int b);

	int Add2(int a, int b);

}

public class Calculator : ICalculator {
	// implementation for Add
	public int Add(int a, int b) {
		return a + b;
	}

	// will fortward call to Add.
	public int Add2(int a, int b) {
		return this.Add(a, b);
	}
}

And then the code is:

ICalculator calc = PolicyInjection.Create<Calculator, ICalculator>();

try {
	// this will not raise a validation exception unless we call Add 
	int result =  calc.Add2(100, 200));
}
catch (ArgumentValidationException ex) {
	foreach (var validation in ex.ValidationResults) {
		Console.WriteLine("Error on : {0}, the error is : {1}", validation.Key, validation.Message);
    	}
}

Thanks

Avi

Jan 28, 2010 at 3:47 AM

That is the expected behavior.  You'll need to have a reference to your policy-enabled class.  So in Add2, you should have this;

Calculator calculator = PolicyInjection.Wrap<Calculator>(this);

calculator.Add(a, b);

 

Sarah Urmeneta
Global Technology and Solutions
Avanade, Inc.
entlib.support@avanade.com

Jan 28, 2010 at 8:53 AM

Ok i get that, but in real life the calculator object is a template subclass class in the form

public abstract class BaseBroker<T, K> : MarshalByRefObject

When i try to use

BaseBroker<T, K> proxy = PolicyInjection.Wrap<BaseBroker<T, K>>(this);

the code fails with the following error :

Type : Microsoft.Practices.Unity.ResolutionFailedException, Microsoft.Practices.Unity, Version=1.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
Message : Resolution of the dependency failed, type = "Vizelia.FOL.BusinessLayer.Broker.BaseBroker`2[Vizelia.FOL.BusinessEntities.PsetAttributeDefinition,Vizelia.FOL.DataLayer.BrokerDB.PsetAttributeDefinitionBrokerDB]", name = "". Exception message is: The current build operation (build key Build Key[Vizelia.FOL.BusinessLayer.Broker.BaseBroker`2[Vizelia.FOL.BusinessEntities.PsetAttributeDefinition,Vizelia.FOL.DataLayer.BrokerDB.PsetAttributeDefinitionBrokerDB], null]) failed: Impossible de créer des instances de classes abstraites. (Strategy type BuildPlanStrategy, index 5)
Source : Microsoft.Practices.Unity

Any idea ?

Cheers

 

 

Jan 29, 2010 at 3:30 AM

Hmm, could you show me your class structure?  I can successfully call the Add method below from a policy-enabled object subclass of BaseBroker

 

public abstract class BaseBroker<T, K> : MarshalByRefObject
{
        protected BaseBroker()
        {
        }

        public void Add()
        {
            BaseBroker<T, K> proxy = PolicyInjection.Wrap<BaseBroker<T, K>>(this);
        }

}

 

Sarah Urmeneta
Global Technology and Solutions
Avanade, Inc.
entlib.support@avanade.com