/// <summary> /// Creates proxy instance /// </summary> /// <param name="baseType"></param> /// <returns></returns> public static object CreateProxy(Type baseType, ProxyOptions options) { var proxyType = GetProxyType(baseType, options); var proxy = Activator.CreateInstance(proxyType); return(proxy); }
public static T Create <T>() where T : INotifyPropertyChanged { var options = new ProxyOptions <T> { OnSet = OnSet }; return(ProxyBuilder.CreateProxy(options)); }
/// <summary> /// Creates proxy instance /// </summary> /// <typeparam name="T">base type</typeparam> /// <returns></returns> public static T CreateProxy <T>(ProxyOptions <T> options) { var baseType = typeof(T); return((T)CreateProxy(baseType, options)); }
/// <summary> /// Creates proxy type which overrides only properties /// </summary> /// <returns></returns> private static Type GetProxyType(Type baseType, ProxyOptions options) { if (ProxyTypes.ContainsKey(baseType)) { return(ProxyTypes[baseType]); } var proxyTypeName = $"{baseType.Name}_Proxy_{Guid.NewGuid():N}"; // proxy is public class inherited from baseType TypeBuilder tb; if (baseType.IsInterface) { tb = ModuleBuilder.DefineType(proxyTypeName, TypeAttributes.Public, null, new[] { baseType }); foreach (var eventInfo in GetPublicEvents(baseType)) { CreateEvent(tb, eventInfo); } } else { tb = ModuleBuilder.DefineType(proxyTypeName, TypeAttributes.Public, baseType); } foreach (var propInfo in GetPublicProperties(baseType)) { var propName = propInfo.Name; var propType = propInfo.PropertyType; // create property PropertyBuilder prop = tb.DefineProperty(propName, PropertyAttributes.SpecialName, propType, null); Lazy <FieldBuilder> backingField = new Lazy <FieldBuilder>( () => tb.DefineField($"_{propName}", propType, FieldAttributes.Private) ); var baseGet = propInfo.GetGetMethod(); if (baseGet != null) { var useBaseGet = !baseType.IsInterface && !baseGet.IsAbstract; var propGetter = useBaseGet ? CreateGetter(propInfo, tb) : CreateGetter(backingField.Value, tb, propName); // assign getter prop.SetGetMethod(propGetter); } var baseSet = propInfo.GetSetMethod(); if (baseSet != null) { var useBaseSet = !baseType.IsInterface && !baseSet.IsAbstract; var propSetter = useBaseSet ? CreateSetter(propInfo, tb, options.OnSet) : CreateSetter(backingField.Value, tb, propName, options.OnSet); // assign setter prop.SetSetMethod(propSetter); } } // default constructor tb.DefineDefaultConstructor(MethodAttributes.Public); // Finish the type. var proxyType = tb.CreateType(); ProxyTypes[baseType] = proxyType; return(proxyType); }