public static Type CreateProxyType (Type requestedType, ContractDescription cd, bool duplex)
{
ClientProxyKey key = new ClientProxyKey (requestedType, cd, duplex);
Type res;
lock (proxy_cache) {
if (proxy_cache.TryGetValue (key, out res))
return res;
}
string modname = "dummy";
Type crtype =
#if !NET_2_1
duplex ? typeof (DuplexClientRuntimeChannel) :
#endif
typeof (ClientRuntimeChannel);
// public class __clientproxy_MyContract : (Duplex)ClientRuntimeChannel, [ContractType]
var types = new List<Type> ();
types.Add (requestedType);
if (!cd.ContractType.IsAssignableFrom (requestedType))
types.Add (cd.ContractType);
if (cd.CallbackContractType != null && !cd.CallbackContractType.IsAssignableFrom (requestedType))
types.Add (cd.CallbackContractType);
CodeClass c = new CodeModule (modname).CreateClass ("__clientproxy_" + cd.Name, crtype, types.ToArray ());
//
// public __clientproxy_MyContract (
// ServiceEndpoint arg1, ChannelFactory arg2, EndpointAddress arg3, Uri arg4)
// : base (arg1, arg2, arg3, arg4)
// {
// }
//
Type [] ctorargs = new Type [] {typeof (ServiceEndpoint), typeof (ChannelFactory), typeof (EndpointAddress), typeof (Uri)};
CodeMethod ctor = c.CreateConstructor (
MethodAttributes.Public, ctorargs);
CodeBuilder b = ctor.CodeBuilder;
MethodBase baseCtor = crtype.GetConstructors (
BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance) [0];
if (baseCtor == null) throw new Exception ("INTERNAL ERROR: ClientRuntimeChannel.ctor() was not found.");
b.Call (
ctor.GetThis (),
baseCtor,
new CodeArgumentReference (typeof (ServiceEndpoint), 1, "arg0"),
new CodeArgumentReference (typeof (ChannelFactory), 2, "arg1"),
new CodeArgumentReference (typeof (EndpointAddress), 3, "arg2"),
new CodeArgumentReference (typeof (Uri), 4, "arg3"));
res = CreateProxyTypeOperations (crtype, c, cd);
lock (proxy_cache) {
proxy_cache [key] = res;
}
return res;
}
}