// ================================================================================================================================ // IInterfaceApplierFactory IMPLEMENTATION // ================================================================================================================================ /// <summary> /// Try to generate an InterfaceApplier for the specified interface (the targetType MUST be an interface, not a class), values returned from properties /// and methods will be passed through the specified readValueConverter in case manipulation is required (eg. applying an interface to particular /// returned property values of the targetType) /// </summary> public IInterfaceApplier GenerateInterfaceApplier(Type targetType, IReadValueConverter readValueConverter) { var generate = this.GetType().GetMethod("GenerateInterfaceApplier", new[] { typeof(IReadValueConverter) }); var generateGeneric = generate.MakeGenericMethod(targetType); return((IInterfaceApplier)generateGeneric.Invoke(this, new[] { readValueConverter })); }
/// <summary> /// Try to generate an InterfaceApplier for the specified interface (the typeparam MUST be an interface, not a class) /// </summary> /// <typeparam name="T">This will always be an interface, never a class</typeparam> public IInterfaceApplier <T> GenerateInterfaceApplier <T>(IReadValueConverter readValueConverter) { if (!typeof(T).IsInterface) { throw new ArgumentException("typeparam must be an interface type", "targetInterface"); } if (readValueConverter == null) { throw new ArgumentNullException("readValueConverter"); } lock (_cache) { if (_cache.ContainsKey(typeof(T))) { return((IInterfaceApplier <T>)_cache[typeof(T)]); } } var interfaceApplier = _interfaceApplierFactory.GenerateInterfaceApplier <T>(readValueConverter); lock (_cache) { if (!_cache.ContainsKey(typeof(T))) { _cache.Add(typeof(T), interfaceApplier); } } return(interfaceApplier); }
/// <summary> /// Try to generate an InterfaceApplier for the specified interface (targetType MUST be an interface, not a class) /// </summary> public IInterfaceApplier GenerateInterfaceApplier(Type targetInterface, IReadValueConverter readValueConverter) { if (targetInterface == null) { throw new ArgumentNullException("targetInterface"); } if (!targetInterface.IsInterface) { throw new ArgumentException("typeparam must be an interface type", "targetInterface"); } if (readValueConverter == null) { throw new ArgumentNullException("readValueConverter"); } return(new InterfaceApplier( targetInterface, new DelayedExecutor <IInterfaceApplier>( () => _reflectionFactory.GenerateInterfaceApplier(targetInterface, readValueConverter) ), new DelayedExecutor <IInterfaceApplier>( () => _idispatchFactory.GenerateInterfaceApplier(targetInterface, readValueConverter) ) )); }
/// <summary> /// Try to generate an InterfaceApplier for the specified interface (targetType MUST be an interface, not a class) /// </summary> public IInterfaceApplier GenerateInterfaceApplier(Type targetInterface, IReadValueConverter readValueConverter) { if (!targetInterface.IsInterface) { throw new ArgumentException("must be an interface type", "targetInterface"); } if (readValueConverter == null) { throw new ArgumentNullException("readValueConverter"); } // We'll pass all requests to this method signature to the generic one so that we know that all entries in the cache are generic IInterfaceApplier // and none are the non-typeparam'd IInterfaceApplier variant var generate = this.GetType().GetMethod("GenerateInterfaceApplier", new[] { typeof(IReadValueConverter) }); var generateGeneric = generate.MakeGenericMethod(targetInterface); return((IInterfaceApplier)generateGeneric.Invoke(this, new[] { readValueConverter })); }
/// <summary> /// Try to generate an InterfaceApplier for the specified interface (the typeparam MUST be an interface, not a class) /// </summary> /// <typeparam name="T">This will always be an interface, never a class</typeparam> public IInterfaceApplier <T> GenerateInterfaceApplier <T>(IReadValueConverter readValueConverter) { if (!typeof(T).IsInterface) { throw new ArgumentException("typeparam must be an interface type"); } if (readValueConverter == null) { throw new ArgumentNullException("readValueConverter"); } return(new InterfaceApplier <T>( new DelayedExecutor <IInterfaceApplier <T> >( () => _reflectionFactory.GenerateInterfaceApplier <T>(readValueConverter) ), new DelayedExecutor <IInterfaceApplier <T> >( () => _idispatchFactory.GenerateInterfaceApplier <T>(readValueConverter) ) )); }
/// <summary> /// Try to generate an InterfaceApplier for the specified interface, values returned from properties and methods will be passed through the specified /// readValueConverter in case manipulation is required (eg. applying an interface to particular returned property values of the targetType) /// </summary> /// <typeparam name="T">This will always be an interface, never a class</typeparam> public IInterfaceApplier <T> GenerateInterfaceApplier <T>(IReadValueConverter readValueConverter) { if (!typeof(T).IsInterface) { throw new ArgumentException("typeparam must be an interface type", "targetInterface"); } if (readValueConverter == null) { throw new ArgumentNullException("readValueConverter"); } var typeName = "ReflectionInterfaceApplier" + Guid.NewGuid().ToString("N"); var typeBuilder = _moduleBuilder.Value.DefineType( typeName, TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.AutoClass | TypeAttributes.AnsiClass | TypeAttributes.BeforeFieldInit | TypeAttributes.AutoLayout, typeof(object), new Type[] { typeof(T) } ); // ================================================================================================ // Add [ComVisible(true)] and [ClassInterface(ClassInterfaceType.None)] attributes to the type so // that we can pass the generated objects through to COM object (eg. WSC controls) if desired // ================================================================================================ if (_createComVisibleClasses) { typeBuilder.SetCustomAttribute( new CustomAttributeBuilder( typeof(ComVisibleAttribute).GetConstructor(new[] { typeof(bool) }), new object[] { true } ) ); typeBuilder.SetCustomAttribute( new CustomAttributeBuilder( typeof(ClassInterfaceAttribute).GetConstructor(new[] { typeof(ClassInterfaceType) }), new object[] { ClassInterfaceType.None } ) ); } // ================================================================================================ // Ensure we account for any interfaces that the target interface implements (recursively) // ================================================================================================ var interfaces = (new InterfaceHierarchyCombiner(typeof(T))).Interfaces; // ================================================================================================ // Declare private "src" and "readValueConverter" fields // ================================================================================================ var srcField = typeBuilder.DefineField("_src", typeof(object), FieldAttributes.Private); var readValueConverterField = typeBuilder.DefineField("_readValueConverter", typeof(IReadValueConverter), FieldAttributes.Private); // ================================================================================================ // Generate the constructor, properties and methods (fields can't be declared on interfaces) // - We won't explicitly generate properties since "get_" and "set_" methods should be present on // .Net classes which will be used automatically // ================================================================================================ generateConstructor(typeBuilder, srcField, readValueConverterField); generateMethods <T>(typeBuilder, srcField, readValueConverterField, interfaces); // ================================================================================================ // Return a new InterfaceApplier references // ================================================================================================ return(new InterfaceApplier <T>( src => (T)Activator.CreateInstance( typeBuilder.CreateType(), src, readValueConverter ) )); }