Interception - Create WCF wrappers

Oct 17, 2010 at 10:17 PM
Edited Oct 18, 2010 at 12:28 AM

Hi Gang,

I've just updated my WCF bible ( Programmng WCF Services - Juval Löwy ) to the third edition, and there is a nice helper class described called WCFWrapper

 

The basic premise is that this abstract class will wrap the WCF plumbing to create in In-Proc WCF service via ChannelFactory<T> where T is the WCF contract interface

 

public abstract class WcfWrapper<I> : IDisposable, ICommunicationObject
  where I : class
{
    protected I Proxy { get; private set; }

    protected WcfWrapper()
    {
        this.Proxy = InProcFactory.CreateInstance<I>();
    }

    /*
    IDisposible and ICommunicationObject implementation
    */
}

To use this, subclass it for each WCF contract

 

[ServiceContract]
interface IMyContract
{
    [OperationContract]
    string MyMethod();
}

class MyContactProxy : WcfWrapper<IMyContract>, IMyContract
{
    public string MyMethod()
    {
        return base.Proxy.MyMethod();
    }
}

 

The underlying InProcFactory uses Unity to resolve a class implementing the WCF contract as the service host, but I still have to create a WCF Proxy for each contract.  I currently used a T4 template to build these proxy classes in my Service Interface assembly.

 

What I would like to do is use either a Object Builder strategy or Interception to create a Proxy object on the fly when I resolve the WCF contract Interface.  I've looked though the InterfaceInterceptor and TransparentProxyInterceptor and they are almost what I need, but the nice bits that do the work are all internal to Unity.Interception ( ie InterfaceImplementation, InterceptingProxyImplementor ).

 

Can you think of a way to do this with what Unity or Unity.Interception exposes, I don't want to have to either change the Unity source code or reimplement the Unity code in my own assemblies if I can help it.

 

Cheers...

 

Robert

 

Oct 18, 2010 at 6:04 AM

The Unity interception stuff doesn't generate anything other than interception proxies - you'd need to hack the code up yourself to codegen the derived classes anyway. I don't know that what's currently there would actually help you that much. I suspect you're going to have to write the codegen bits yourself.

You might be able to implement it as an interception behavior over an interface, but I don't know enough WCF or how that class works to know if it'll work.

 

Oct 19, 2010 at 3:26 AM
Edited Oct 19, 2010 at 3:31 AM

Hi Chris,

 

That is what I suspected.  The interception doesn't work directly as I still need to have an implementation of the contract interface in order for the Interception system to have something to intercept.

I ended up creating a container extension that intercepts the Registering event and switches the registration under the hood.  The ProxyClassGenerator uses the TypeBuilder system to generate the proxy class ( borrowed heavily from the Interception codegen classes )

The GetCustomAttribute<> extension is a type safe wrapper around System.MemberInfo.GetCustomAttributes()

    IUnityContainer container = new UnityContainer()
        .AddNewExtension<ProxyBuilderExtension>()
        .RegisterType<IMyContract>();

    IMyContract proxy = Container.Resolve<IMyContract>();


    public class ProxyBuilderExtension : UnityContainerExtension
    {
        protected override void Initialize()
        {
            base.Context.Registering += (sender, args) =>
                                            {
                                               // Only action registrations where the interface has been registered without implementation AND the interface is decorated with the ServiceContract attribute 
                                               if ( args.TypeFrom != null && !args.TypeTo.IsInterface && args.TypeTo.GetCustomAttribute<System.ServiceModel.ServiceContractAttribute>() == null)
                                                    return;
                                                
                                                Type wrapperType = typeof(WcfWrapper<>).MakeGenericType(args.TypeTo);
                                                Type proxyImpl = ProxyClassGenerator.GenerateType(wrapperType, args.TypeTo);

                                                // Override the registration and create a new build policy
                                                base.Context.RegisterNamedType( args.TypeTo, args.Name);
                                                base.Context.Policies.Set<IBuildKeyMappingPolicy>(new BuildKeyMappingPolicy(new NamedTypeBuildKey(proxyImpl, args.Name)), new NamedTypeBuildKey(args.TypeTo, args.Name));
                                            };
        }
    }



 

 

 

Feb 19, 2013 at 5:43 PM
Can you share ProxyClassGenerator source code? Thanks