Policy Injection Application Block Questions

Topics: Policy Injection Application Block
Mar 3, 2007 at 3:01 PM
The documentation says this:

"If the block determines that the configuration does not specify any matching Handlers, the Create method just returns a new instance of the target class."

I am taking this to mean that if I have a class such as:

    public class Subscriber : MarshalByRefObject
    {
        private string _name;
        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }
 
        private string _emailAddress;
        public string EmailAddress
        {
            get { return _emailAddress; }
            set { _emailAddress = value; }
        }
    }

and call the following:

Subscriber subscriber = PolicyInjection.Create<Subscriber>();

that the Create Method should just return an instance of the Subscriber Class since there are no handlers in the config file for the Subscriber Class. In fact I have no policies in the config file. All I have is this:

<section name="policyInjection" type="Microsoft.Practices.EnterpriseLibrary.PolicyInjection.Configuration.PolicyInjectionSettings, Microsoft.Practices.EnterpriseLibrary.PolicyInjection, Version=2.9.9.2, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />


However, the current Feb 2007 CTP return an instance of the proxy class instead of the actual class instance.

And, even though I might have some classes that will never have policies on them, why is it that they need to be derived from MarshalByRefObject? Perhaps if the class is not derived from MarshalByRefObject you just return an instance of the class.

Hence if I have a class like this derived from Object:

    public class Subscriber
    {
        private string _name;
        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }
 
        private string _emailAddress;
        public string EmailAddress
        {
            get { return _emailAddress; }
            set { _emailAddress = value; }
        }
    }

I would expect this:

Subscriber subscriber = PolicyInjection.Create<Subscriber>();

to always return an instance of Subscriber as opposed to giving me an exception telling me the class needs to derive from MarshalByRefObject.

My thought is that I might create all my objects via PolicyInjection.Create<T> for future-proofing assuming there isn't that much of a performance hit. Is this a good idea?

Regards,

Dave

__________________________

David Hayden
Microsoft MVP C#
Mar 3, 2007 at 6:44 PM
Hi Dave -

The documentation matches the expected behavior - if no policies are defined for a type, you get the object back instead of a proxy. I'm not sure if it's a CTP bug or something odd about what you're doing, but we've tested this against our current bits and it seems to be working.

You raise an interesting question about whether the MBRO requirement should be enforced if no policies exist. At the moment it is not being enforced - although you're seeing the check because you're getting a proxy anyway for some reason. However after thinking about this more, I'm not convinced this is the right decision. A key idea of the PIAB is that you should be able to define policies in the future without changing code. If the MBRO check isn't done every time, it's likely that people won't know that their classes aren't PIAB-friendly until they try applying policies later in the process, at which time it may be too late. What do you think about this?

BTW, the MBRO requirement is needed by our remoting proxy interception mechanism (if you don't use explicit interfaces), but different interception mechanisms have different restrictions. So any checks of this nature would be encapsulated in the interception implementation, and not on the PolicyInjection façade or in the handler pipeline.

Tom
Mar 3, 2007 at 11:20 PM
Tom,

Your logic seems sound on forcing the MBRO check for the ability to add policies later without forcing a code change later that requires the class inherit from MBRO. I haven't totally wrapped my head around how I would use the PIAB yet, so I couldn't say if this has any huge drawbacks.

At the time I didn't realize I could use Interfaces with the PIAB, so I have been using Interfaces instead of MBRO for the past few hours.

As far as my problem above, I guess I don't know if and when I get the proxy vs. the actual class. I know the policy injection is working fine. I assumed if I did a GetType() on the object returned from the PolicyInjection.Create() statment that I would get differing types depending on if there is a policy / handlers defined or not. I seem to always get the same type which has me a bit confused. I will let it go for now and think about something else :)

Regards,

Dave

_____________________

David Hayden
Microsoft MVP C#
Mar 5, 2007 at 12:47 AM
Aha - that's the magic of the __TransparentProxy class at work. The CLR allows it to stand in for the real class, even to the extent of lying about what type it is when calling GetType!

Tom
Mar 5, 2007 at 3:41 AM
If you want to tell if you've got a proxy or not, you can call RemotingServices.IsTransparentProxy(). If true, you've got a proxy, if false you've got the "real" object.

The CLR's got some special case tricks in the type system to let TransparentProxy object act like other types. It's one of the reasons we implemented the current interception mechanism using them.
Mar 5, 2007 at 3:33 PM
Great! That is exactly what I was looking for. But it doesn't explain why it returns true when all I have in my application is the following:

class Program
{
    static void Main(string[] args)
    {
        IOrder order = PolicyInjection.Create<Order, IOrder>();
        bool isProxy = RemotingServices.IsTransparentProxy(order); // Returns True!
    }
}
 
public class Order : IOrder {}
 
public interface IOrder {}

with an App.Config of:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <configSections>
		<section name="policyInjection" type="Microsoft.Practices.EnterpriseLibrary.PolicyInjection.Configuration.PolicyInjectionSettings, Microsoft.Practices.EnterpriseLibrary.PolicyInjection, Version=2.9.9.2, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
	</configSections>
</configuration>

The isProxy equals true which is driving me crazy.

Will this act differently while debugging in the IDE such that it will always return a remote proxy?

I assume it should return false?

Regards,

Dave

______________________

David Hayden
Microsoft MVP C#