From e3afbae213be0f211c0562ec2e2fd1e7eed1d91e Mon Sep 17 00:00:00 2001 From: David Fowler Date: Sat, 19 Apr 2014 02:27:17 -0700 Subject: [PATCH] Remove the converter logic --- .../FeatureCollection.cs | 6 +- .../FeatureObject.cs | 15 - .../Implementation/Converter.cs | 388 ------------------ .../Microsoft.AspNet.FeatureModel.kproj | 1 - 4 files changed, 1 insertion(+), 409 deletions(-) delete mode 100644 src/Microsoft.AspNet.FeatureModel/Implementation/Converter.cs diff --git a/src/Microsoft.AspNet.FeatureModel/FeatureCollection.cs b/src/Microsoft.AspNet.FeatureModel/FeatureCollection.cs index d3aaff33cf..00d2a38e4f 100644 --- a/src/Microsoft.AspNet.FeatureModel/FeatureCollection.cs +++ b/src/Microsoft.AspNet.FeatureModel/FeatureCollection.cs @@ -3,7 +3,6 @@ using System.Collections; using System.Collections.Generic; using System.Reflection; using System.Threading; -using Microsoft.AspNet.FeatureModel.Implementation; namespace Microsoft.AspNet.FeatureModel { @@ -49,11 +48,8 @@ namespace Microsoft.AspNet.FeatureModel { return feature; } -#if NET45 - return Converter.Convert(type, actualType, feature); -#else + return null; -#endif } } diff --git a/src/Microsoft.AspNet.FeatureModel/FeatureObject.cs b/src/Microsoft.AspNet.FeatureModel/FeatureObject.cs index 42d2bf8e79..d937d09dc5 100644 --- a/src/Microsoft.AspNet.FeatureModel/FeatureObject.cs +++ b/src/Microsoft.AspNet.FeatureModel/FeatureObject.cs @@ -3,7 +3,6 @@ using System.Collections; using System.Collections.Generic; using System.Reflection; using System.Linq; -using Microsoft.AspNet.FeatureModel.Implementation; namespace Microsoft.AspNet.FeatureModel { @@ -32,20 +31,6 @@ namespace Microsoft.AspNet.FeatureModel return _instance; } -#if NET45 - foreach (var interfaceType in _instance.GetType().GetInterfaces()) - { - if (interfaceType.FullName == type.FullName) - { - return Converter.Convert(interfaceType, type, _instance); - } - } -#else - if (_instance != null && type == _instance.GetType()) - { - return _instance; - } -#endif return null; } diff --git a/src/Microsoft.AspNet.FeatureModel/Implementation/Converter.cs b/src/Microsoft.AspNet.FeatureModel/Implementation/Converter.cs deleted file mode 100644 index 0102dea38a..0000000000 --- a/src/Microsoft.AspNet.FeatureModel/Implementation/Converter.cs +++ /dev/null @@ -1,388 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -#if NET45 -using System.Reflection.Emit; -#endif -using System.Runtime.CompilerServices; - -namespace Microsoft.AspNet.FeatureModel.Implementation -{ - #if NET45 - public abstract class NonGenericProxyBase - { - public readonly Type WrappedType; - protected NonGenericProxyBase(Type wrappedType) - { - this.WrappedType = wrappedType; - } - public abstract object UnderlyingInstanceAsObject - { - get; - } - } - - public class BaseType : NonGenericProxyBase where T : class - { - protected T instance; - public BaseType(T inst) - : base(typeof(T)) - { - if (inst == null) throw new InvalidOperationException("should never construct proxy over null"); - this.instance = inst; - } - public T UnderlyingInstance - { - get - { - return instance; - } - } - public override object UnderlyingInstanceAsObject - { - get - { - return instance; - } - } - } - - public class Converter - { - public static object Convert(Type outputType, Type inputType, object input) - { - if (inputType == outputType) return input; - - if (!inputType.IsInterface || !outputType.IsInterface) throw new InvalidOperationException("Both types must be interfaces"); - - if (inputType.GetInterfaces().Contains(outputType)) return input; - - if (input == null) return null; - - Type t = EnsureConverter(outputType, inputType); - - return Activator.CreateInstance(t, input); - } - - public static TOut Convert(Type inputType, object input) - where TOut : class - { - return (TOut)Convert(typeof (TOut), inputType, input); - } - - public static TOut Convert(TIn input) - where TIn : class - where TOut : class - { - return Convert(typeof(TIn), input); - } - - public static TOut Convert(object input) - where TOut : class - { - if (input == null) return null; - var interfaceName = typeof(TOut).FullName; - foreach (var inputType in input.GetType().GetInterfaces()) - { - if (inputType.FullName == interfaceName) - { - return Convert(inputType, input); - } - } - return null; - } - - - public static Type EnsureConverter(Type tout, Type tin) - { - CacheResult result; - if (!ConverterTypeCache.TryGetValue(new Tuple(tin, tout), out result)) - { - EnsureCastPossible(tout, tin); - return EnsureConverter(tout, tin); - } - else - { - if (result is ErrorResult) - { - throw new InvalidCastException((result as ErrorResult).error); - } - else if (result is CurrentlyVerifyingResult) - { - throw new InvalidOperationException("Type cannot be obtained in verification phase"); - } - else if (result is TypeBuilderResult) - { - return (result as TypeBuilderResult).result; - } - else if (result is VerificationSucceededResult) - { - return CreateWrapperType(tout, tin, result as VerificationSucceededResult); - } - else - { - throw new InvalidOperationException("Invalid cache state"); - } - } - } - - class CacheResult - { - } - - class TypeBuilderResult : CacheResult - { - internal TypeBuilderResult(Type result) - { - this.result = result; - } - internal readonly Type result; - } - class ErrorResult : CacheResult - { - internal ErrorResult(string error) - { - this.error = error; - } - internal readonly string error; - } - class CurrentlyVerifyingResult : CacheResult - { - } - enum SuccessKind - { - Identity, - SubInterface, - Wrapper, - } - class VerificationSucceededResult : CacheResult - { - internal VerificationSucceededResult(SuccessKind kind) - { - this.kind = kind; - } - internal VerificationSucceededResult(Dictionary mappings) - { - this.kind = SuccessKind.Wrapper; - this.methodMappings = mappings; - } - internal readonly SuccessKind kind; - internal readonly Dictionary methodMappings; - } - - static Dictionary, CacheResult> ConverterTypeCache = new Dictionary, CacheResult>(); - static ConditionalWeakTable ConverterInstanceCache = new ConditionalWeakTable(); - static AssemblyBuilder ab = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("ProxyHolderAssembly"), AssemblyBuilderAccess.Run); - static ModuleBuilder modb = ab.DefineDynamicModule("Main Module"); - - class EqComparer : IEqualityComparer - { - - bool IEqualityComparer.Equals(ParameterInfo x, ParameterInfo y) - { - return EqualTypes(x.ParameterType, y.ParameterType); - } - - int IEqualityComparer.GetHashCode(ParameterInfo obj) - { - return obj.GetHashCode(); - } - } - - static bool EqualTypes(Type sourceType, Type targetType) - { - return EnsureCastPossible(targetType, sourceType); - } - - - - static MethodInfo FindCorrespondingMethod(Type targetType, Type sourceType, MethodInfo miTarget) - { - MethodInfo[] sms = sourceType.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).Where((MethodInfo mi) => mi.Name == miTarget.Name).ToArray(); - if (sms != null && sms.Length != 0) - { - MethodInfo[] sm = null; - try - { - sm = sms.Where((mi) => (mi.GetParameters().SequenceEqual(miTarget.GetParameters(), new EqComparer()))).ToArray(); - } - catch - { - } - if (sm != null && sm.Length != 0) - { - if (sm.Length > 1) return null; - if (EqualTypes(sm[0].ReturnType, miTarget.ReturnType)) - { - return sm[0]; - } - } - } - MethodInfo[] rval = sourceType.GetInterfaces().Select((inheritedItf) => FindCorrespondingMethod(targetType, inheritedItf, miTarget)).ToArray(); - if (rval == null || rval.Length == 0) return null; - if (rval.Length > 1) return null; - return rval[0]; - - } - - - static void AddMethod(Type targetType, Type sourceType, TypeBuilder tb, MethodInfo miTarget, MethodInfo miSource) - { - ParameterInfo[] pisTarget = miTarget.GetParameters(); - ParameterInfo[] pisSource = miSource.GetParameters(); - MethodBuilder metb; - Type[] typesTarget; - if (pisTarget == null || pisTarget.Length == 0) - { - metb = tb.DefineMethod(miTarget.Name, MethodAttributes.Virtual, CallingConventions.HasThis, miTarget.ReturnType, null); - pisTarget = new ParameterInfo[0]; - typesTarget = new Type[0]; - } - else - { - typesTarget = pisTarget.Select((pi) => pi.ParameterType).ToArray(); - Type[][] requiredCustomMods = pisTarget.Select((pi) => pi.GetRequiredCustomModifiers()).ToArray(); - Type[][] optionalCustomMods = pisTarget.Select((pi) => pi.GetOptionalCustomModifiers()).ToArray(); - - metb = tb.DefineMethod(miTarget.Name, MethodAttributes.Virtual, CallingConventions.HasThis, miTarget.ReturnType, null, null, typesTarget, requiredCustomMods, optionalCustomMods); - } - - ILGenerator il = metb.GetILGenerator(); - il.Emit(OpCodes.Ldarg_0); - il.Emit(OpCodes.Ldfld, tb.BaseType.GetField("instance", BindingFlags.NonPublic | BindingFlags.Instance)); - for (int pi = 0; pi < pisTarget.Length; pi++) - { - il.Emit(OpCodes.Ldarg, pi + 1); - EmitParamConversion(il, typesTarget[pi], pisSource[pi].ParameterType); - } - il.EmitCall(OpCodes.Callvirt, miSource, null); - - EmitParamConversion(il, miSource.ReturnType, miTarget.ReturnType); - il.Emit(OpCodes.Ret); - - tb.DefineMethodOverride(metb, miTarget); - } - - static void EmitParamConversion(ILGenerator il, Type typeOnStack, Type typeRequiredInSignature) - { - if (typeOnStack != typeRequiredInSignature) - { - if (typeOnStack.GetInterfaces().Contains(typeRequiredInSignature)) - { - il.Emit(OpCodes.Castclass, typeRequiredInSignature); - } - else - { - Label lEnd = il.DefineLabel(); - Label lCreateProxy = il.DefineLabel(); - il.Emit(OpCodes.Dup); // o o - il.Emit(OpCodes.Brfalse_S, lEnd); // o - il.Emit(OpCodes.Dup); // o o - il.Emit(OpCodes.Isinst, typeof(NonGenericProxyBase)); // o [p/n] - il.Emit(OpCodes.Brfalse_S, lCreateProxy); // o - il.Emit(OpCodes.Isinst, typeof(NonGenericProxyBase)); // p - il.EmitCall(OpCodes.Callvirt, typeof(NonGenericProxyBase).GetMethod("get_UnderlyingInstanceAsObject"), null); // uo - il.Emit(OpCodes.Dup); // uo uo - il.Emit(OpCodes.Isinst, typeRequiredInSignature); // uo [ro/n] - il.Emit(OpCodes.Brtrue_S, lEnd); // uo - il.MarkLabel(lCreateProxy); // uo - Type paramProxyType = EnsureConverter(typeRequiredInSignature, typeOnStack); - il.Emit(OpCodes.Newobj, paramProxyType.GetConstructors()[0]); - il.MarkLabel(lEnd); // ro - } - } - } - - - - static bool EnsureCastPossible(Type targetType, Type sourceType) - { - var key = new Tuple(sourceType, targetType); - CacheResult cr = null; - if (ConverterTypeCache.TryGetValue(key, out cr)) - { - if (cr is CurrentlyVerifyingResult || cr is VerificationSucceededResult || cr is TypeBuilderResult) return true; - if (cr is ErrorResult) return false; - } - if (targetType == sourceType) - { - ConverterTypeCache[key] = new VerificationSucceededResult(SuccessKind.Identity); - return true; - } - if (targetType.GetInterfaces().Contains(sourceType)) - { - ConverterTypeCache[key] = new VerificationSucceededResult(SuccessKind.SubInterface); - return true; - } - if (!targetType.IsInterface || !sourceType.IsInterface) - { - ConverterTypeCache[key] = new ErrorResult("Cannot cast " + sourceType + " to " + targetType); - return false; - } - bool success = false; - ConverterTypeCache[key] = new CurrentlyVerifyingResult(); - try - { - Dictionary mappings = new Dictionary(); - foreach (MethodInfo mi in targetType.GetMethods().Concat(targetType.GetInterfaces().SelectMany((itf) => itf.GetMethods()))) - { - MethodInfo mapping = FindCorrespondingMethod(targetType, sourceType, mi); - if (mapping == null) - { - ConverterTypeCache[key] = new ErrorResult("Can not cast " + sourceType + " to " + targetType + " because of missing method: " + mi.Name); - return false; - } - mappings[mi] = mapping; - } - ConverterTypeCache[key] = new VerificationSucceededResult(mappings); - success = true; - return true; - } - finally - { - if (!success) - { - if (!(ConverterTypeCache[key] is ErrorResult)) - { - ConverterTypeCache[key] = new ErrorResult("Can not cast " + sourceType + " to " + targetType); - } - } - } - } - - static int counter = 0; - static Type CreateWrapperType(Type targetType, Type sourceType, VerificationSucceededResult result) - { - Dictionary mappings = result.methodMappings; - Type baseType = typeof(BaseType<>).MakeGenericType(sourceType); - TypeBuilder tb = modb.DefineType("ProxyType" + counter++ + " wrapping:" + sourceType.Name + " to look like:" + targetType.Name, TypeAttributes.Class, baseType, new Type[] { targetType }); - ConstructorBuilder cb = tb.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, new Type[] { sourceType }); - ILGenerator il = cb.GetILGenerator(); - il.Emit(OpCodes.Ldarg_0); - il.Emit(OpCodes.Ldarg_1); - il.Emit(OpCodes.Castclass, sourceType); - il.Emit(OpCodes.Call, baseType.GetConstructor(new Type[] { sourceType })); - il.Emit(OpCodes.Ret); - var tuple = new Tuple(sourceType, targetType); - try - { - ConverterTypeCache[tuple] = new TypeBuilderResult(tb); - foreach (MethodInfo mi in targetType.GetMethods().Concat(targetType.GetInterfaces().SelectMany((itf) => itf.GetMethods()))) - { - AddMethod(targetType, sourceType, tb, mi, mappings[mi]); - } - Type t = tb.CreateType(); - ConverterTypeCache[tuple] = new TypeBuilderResult(t); - return t; - } - catch (Exception e) - { - ConverterTypeCache[tuple] = new ErrorResult(e.Message); - throw; - } - } - - } - #endif -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.FeatureModel/Microsoft.AspNet.FeatureModel.kproj b/src/Microsoft.AspNet.FeatureModel/Microsoft.AspNet.FeatureModel.kproj index e0f6a454d3..7a566cbcf8 100644 --- a/src/Microsoft.AspNet.FeatureModel/Microsoft.AspNet.FeatureModel.kproj +++ b/src/Microsoft.AspNet.FeatureModel/Microsoft.AspNet.FeatureModel.kproj @@ -23,7 +23,6 @@ - \ No newline at end of file