private IEnumerable <MethodInfo> GetMethodsMissingFromInstance(IEnumerable <MethodInfo> methods, object instance) { var instanceSupportsMethod = DynamicInterfaceExtensions.GenerateInstanceSupportsMethod(instance); var instanceType = instance.GetType(); var instanceMethods = instanceType.GetPublicMethods(); var instanceFields = instanceType.GetPublicDelegateFields(); var instanceProperties = instanceType.GetPublicDelegateProperties(); // later, we can check for a delegate-creation function that can deliver a delegate to us by name and parameter types. // currently, we don't need that, so we're not going to implement it right away. return(methods.Where(method => !instanceSupportsMethod(method.Name) || ( instanceMethods.FindMethod(method) == null && instanceFields.FindDelegate(instance, method) == null && instanceProperties.FindDelegate(instance, method) == null ))); }
private object CreateProxy(Type tInterface, params object[] instances) { var matrix = instances.SelectMany(instance => { var instanceType = instance.GetType(); // get all the public interfaces for the instances and place them at the top // and let it try to bind against those. return(instanceType.GetInterfaces().Where(each => each.IsPublic).Select(each => new { instance, SupportsMethod = DynamicInterfaceExtensions.GenerateInstanceSupportsMethod(instance), Type = each, Methods = each.GetPublicMethods(), Fields = each.GetPublicDelegateFields(), Properties = each.GetPublicDelegateProperties() }).ConcatSingleItem(new { instance, SupportsMethod = DynamicInterfaceExtensions.GenerateInstanceSupportsMethod(instance), Type = instanceType, Methods = instanceType.GetPublicMethods(), Fields = instanceType.GetPublicDelegateFields(), Properties = instanceType.GetPublicDelegateProperties() })); }).ToArray(); var instanceMethods = new OrderedDictionary <Type, List <MethodInfo, MethodInfo> >(); var delegateMethods = new List <Delegate, MethodInfo>(); var stubMethods = new List <MethodInfo>(); var usedInstances = new List <Type, object>(); foreach (var method in tInterface.GetVirtualMethods()) { // figure out where it's going to get implemented var found = false; foreach (var instance in matrix) { if (method.Name == "IsMethodImplemented") { // skip for now, we'll implement this at the end found = true; break; } if (instance.SupportsMethod(method.Name)) { var instanceMethod = instance.Methods.FindMethod(method); if (instanceMethod != null) { instanceMethods.GetOrAdd(instance.Type, () => new List <MethodInfo, MethodInfo>()).Add(method, instanceMethod); if (!usedInstances.Contains(instance.Type, instance.instance)) { usedInstances.Add(instance.Type, instance.instance); } found = true; break; } var instanceDelegate = instance.Fields.FindDelegate(instance.instance, method) ?? instance.Properties.FindDelegate(instance.instance, method); if (instanceDelegate != null) { delegateMethods.Add(instanceDelegate, method); found = true; break; } } } if (!found && (tInterface.IsInterface || method.IsAbstract)) { #if DEEPDEBUG Debug.WriteLine(" Generating stub method for {0} -> {1}".format(typeof(TInterface).NiceName(), method.ToSignatureString())); #endif stubMethods.Add(method); } } // now we can calculate the key based on the content of the *Methods collections var key = tInterface.FullName + ":::" + instanceMethods.Keys.Select(each => each.FullName + "." + instanceMethods[each].Select(mi => mi.Value.ToSignatureString()).JoinWithComma()).JoinWith(";\r\n") + "::" + delegateMethods.Select(each => each.GetType().FullName).JoinWith(";\r\n") + "::" + stubMethods.Select(mi => mi.ToSignatureString()).JoinWithComma(); var proxyClass = _proxyClassDefinitions.GetOrAdd(key, () => new ProxyClass(tInterface, instanceMethods, delegateMethods, stubMethods)); return(proxyClass.CreateInstance(usedInstances, delegateMethods)); }
private static object CreateProxy(Type tInterface, params object[] instances) { var matrix = instances.SelectMany(instance => { var instanceType = instance.GetType(); // get all the public interfaces for the instances and place them at the top // and let it try to bind against those. return(instanceType.GetInterfaces().Where(each => each.IsPublic).Select(each => new { instance, SupportsMethod = DynamicInterfaceExtensions.GenerateInstanceSupportsMethod(instance), Type = each, Methods = each.GetPublicMethods(), Fields = each.GetPublicDelegateFields(), Properties = each.GetPublicDelegateProperties() }).ConcatSingleItem(new { instance, SupportsMethod = DynamicInterfaceExtensions.GenerateInstanceSupportsMethod(instance), Type = instanceType, Methods = instanceType.GetPublicMethods(), Fields = instanceType.GetPublicDelegateFields(), Properties = instanceType.GetPublicDelegateProperties() })); }).ToArray(); var instanceMethods = new OrderedDictionary <Type, List <MethodInfo, MethodInfo> >(); var delegateMethods = new List <Delegate, MethodInfo>(); var stubMethods = new List <MethodInfo>(); var usedInstances = new List <Type, object>(); foreach (var method in tInterface.GetVirtualMethods()) { // figure out where it's going to get implemented var found = false; foreach (var instance in matrix) { if (method.Name == "IsMethodImplemented") { // skip for now, we'll implement this at the end found = true; break; } if (instance.SupportsMethod(method.Name)) { var instanceMethod = instance.Methods.FindMethod(method); if (instanceMethod != null) { instanceMethods.GetOrAdd(instance.Type, () => new List <MethodInfo, MethodInfo>()).Add(method, instanceMethod); if (!usedInstances.Contains(instance.Type, instance.instance)) { usedInstances.Add(instance.Type, instance.instance); } found = true; break; } var instanceDelegate = instance.Fields.FindDelegate(instance.instance, method) ?? instance.Properties.FindDelegate(instance.instance, method); if (instanceDelegate != null) { delegateMethods.Add(instanceDelegate, method); found = true; break; } } } if (!found && (tInterface.IsInterface || method.IsAbstract)) { #if xDEEPDEBUG Console.WriteLine(" Generating stub method for {0} -> {1}".format(tInterface.NiceName(), method.ToSignatureString())); #endif stubMethods.Add(method); } } return(DynamicType.Create(tInterface, instanceMethods, delegateMethods, stubMethods, usedInstances)); }