Last active
          September 26, 2025 07:05 
        
      - 
      
 - 
        
Save noam-honig/14626d4fb1ee38a35d6e1cc21d4660c3 to your computer and use it in GitHub Desktop.  
    Fix for Column Wizard issue with reference to Application
  
        
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | using System; | |
| using System.Collections.Generic; | |
| using System.IO; | |
| using System.Reflection; | |
| using System.Reflection.Emit; | |
| namespace ENV | |
| { | |
| public class AbstractFactory | |
| { | |
| static Dictionary<string, Dictionary<string, Type>> _cache = new Dictionary<string, Dictionary<string, Type>>(); | |
| public static object CreateInstance(Type t) | |
| { | |
| if (!t.IsAbstract && !t.IsInterface) | |
| return System.Activator.CreateInstance(t); | |
| return CreateInstance(t, () => | |
| { | |
| var ns = t.Namespace; | |
| var baseName = t.Assembly.GetName().Name; | |
| if (baseName.EndsWith("Base")) | |
| { | |
| baseName = baseName.Remove(baseName.Length - 4); | |
| } | |
| if (baseName.EndsWith("Interfaces")) | |
| baseName = baseName.Remove(baseName.Length - 10); | |
| if (ns.StartsWith(baseName)) | |
| { | |
| if (ns.Length > baseName.Length) | |
| { | |
| var i = ns.IndexOf('.', baseName.Length + 1); | |
| if (i > 0) | |
| ns = ns.Remove(i); | |
| } | |
| } | |
| if (WindowsFormsDesignMode && t.IsAbstract) | |
| { | |
| Type CreateFakeApplicationClassForWindowsFormsDesigner(Type baseType) | |
| { | |
| // Find parameterless base ctor (public or non-public). | |
| var baseCtor = baseType.GetConstructor( | |
| BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, | |
| binder: null, | |
| types: Type.EmptyTypes, | |
| modifiers: null); | |
| if (baseCtor == null) | |
| throw new InvalidOperationException("Application must have a parameterless constructor."); | |
| // Create an in-memory dynamic assembly/module (OK for .NET Framework). | |
| var an = new AssemblyName("DynamicAppAssembly"); | |
| System.Reflection.Emit.AssemblyBuilder ab; | |
| #if NET6_0_OR_GREATER | |
| ab = | |
| System.Reflection.Emit.AssemblyBuilder.DefineDynamicAssembly( | |
| new System.Reflection.AssemblyName("DynamicAppAssembly"), | |
| System.Reflection.Emit.AssemblyBuilderAccess.Run); | |
| #else | |
| ab = | |
| System.AppDomain.CurrentDomain.DefineDynamicAssembly( | |
| new System.Reflection.AssemblyName("DynamicAppAssembly"), | |
| System.Reflection.Emit.AssemblyBuilderAccess.Run); | |
| #endif | |
| var mb = ab.DefineDynamicModule("DynamicAppModule"); | |
| // public class DummyApplication : Application { public DummyApplication() : base() {} } | |
| var tb = mb.DefineType( | |
| "DummyApplication", | |
| TypeAttributes.Public | TypeAttributes.Class, | |
| baseType); | |
| // Define public parameterless ctor that calls base .ctor() | |
| var cb = tb.DefineConstructor( | |
| MethodAttributes.Public, | |
| CallingConventions.Standard, | |
| Type.EmptyTypes); | |
| var il = cb.GetILGenerator(); | |
| il.Emit(OpCodes.Ldarg_0); // this | |
| il.Emit(OpCodes.Call, baseCtor); | |
| il.Emit(OpCodes.Ret); | |
| // Implement all abstract methods with default return values | |
| var methods = baseType.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); | |
| foreach (var method in methods) | |
| { | |
| if (method.IsAbstract) | |
| { | |
| var paramTypes = Array.ConvertAll(method.GetParameters(), p => p.ParameterType); | |
| var mbuilder = tb.DefineMethod( | |
| method.Name, | |
| MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig, | |
| method.CallingConvention, | |
| method.ReturnType, | |
| paramTypes); | |
| // Define parameters | |
| for (int i = 0; i < paramTypes.Length; i++) | |
| { | |
| mbuilder.DefineParameter(i + 1, method.GetParameters()[i].Attributes, method.GetParameters()[i].Name); | |
| } | |
| var mil = mbuilder.GetILGenerator(); | |
| if (method.ReturnType == typeof(void)) | |
| { | |
| mil.Emit(OpCodes.Ret); | |
| } | |
| else | |
| { | |
| if (method.ReturnType.IsValueType) | |
| { | |
| var local = mil.DeclareLocal(method.ReturnType); | |
| mil.Emit(OpCodes.Ldloca_S, local); | |
| mil.Emit(OpCodes.Initobj, method.ReturnType); | |
| mil.Emit(OpCodes.Ldloc, local); | |
| } | |
| else | |
| { | |
| mil.Emit(OpCodes.Ldnull); | |
| } | |
| mil.Emit(OpCodes.Ret); | |
| } | |
| tb.DefineMethodOverride(mbuilder, method); | |
| } | |
| } | |
| return tb.CreateType(); | |
| } | |
| var fakeApplication = CreateFakeApplicationClassForWindowsFormsDesigner(t); | |
| return () => Activator.CreateInstance(fakeApplication); | |
| } | |
| string fn = GuessTypeName(t); | |
| return () => CreateInstance(ns, fn); | |
| }); | |
| } | |
| public static T CreateInstance<T>() | |
| { | |
| return (T)CreateInstance(typeof(T)); | |
| } | |
| public static void AddFactory(Type requestedType, Type implementationType) | |
| { | |
| _factoryPerType.Add(requestedType, () => Activator.CreateInstance(implementationType)); | |
| } | |
| public static void AddFactory(Type requestedType, Func<object> factory) | |
| { | |
| _factoryPerType.Add(requestedType, factory); | |
| } | |
| internal static void Clear() | |
| { | |
| _cache.Clear(); | |
| _factoryPerType.Clear(); | |
| } | |
| public static void AddFactory(Type requestedType, string implementationsAssemblyName, string implementationFullTypeName) | |
| { | |
| _factoryPerType.Add(requestedType, () => CreateInstance(implementationsAssemblyName, implementationFullTypeName)); | |
| } | |
| private static string GuessTypeName(Type t) | |
| { | |
| var fn = t.FullName + _coreSuffix; | |
| if (t.IsInterface && t.Name.StartsWith("I")) | |
| { | |
| fn = t.FullName; | |
| fn = fn.Remove(fn.LastIndexOf(".I") + 1, 1); | |
| } | |
| return fn; | |
| } | |
| public static T Create<T>() | |
| { | |
| return CreateInstance<T>(); | |
| } | |
| public static T CreateInstance<T>(string assemblyName) | |
| { | |
| var t = typeof(T); | |
| return (T)CreateInstance(t, () => () => CreateInstance(assemblyName, GuessTypeName(t))); | |
| } | |
| public static T CreateInstance<T>(string assemblyName, string typeFullName) | |
| { | |
| var t = typeof(T); | |
| return (T)CreateInstance(t, () => () => CreateInstance(assemblyName, typeFullName)); | |
| } | |
| static Dictionary<Type, Func<object>> _factoryPerType = new Dictionary<Type, Func<object>>(); | |
| static string _coreSuffix = "Core"; | |
| public static object CreateInstance(Type t, Func<Func<object>> provideFactory) | |
| { | |
| Func<object> result; | |
| if (!_factoryPerType.TryGetValue(t, out result)) | |
| { | |
| lock (_factoryPerType) | |
| { | |
| if (!_factoryPerType.TryGetValue(t, out result)) | |
| { | |
| _factoryPerType.Add(t, result = provideFactory()); | |
| } | |
| } | |
| } | |
| return result(); | |
| } | |
| static bool _figuredOutEntryPath = false; | |
| static string _entryPath = null; | |
| static bool AssemblyExists(string ass) | |
| { | |
| if (File.Exists(ass + ".dll") || File.Exists(ass + ".exe")) | |
| return true; | |
| if (!_figuredOutEntryPath) | |
| { | |
| _figuredOutEntryPath = true; | |
| var x = System.Reflection.Assembly.GetExecutingAssembly(); | |
| if (x != null) | |
| { | |
| _entryPath = Path.GetDirectoryName(x.CodeBase).Substring(6); | |
| } | |
| } | |
| if (_entryPath == null) | |
| return false; | |
| var nameInEntry = Path.Combine(_entryPath, ass); | |
| return File.Exists(nameInEntry + ".dll") && !File.Exists(nameInEntry + ".exe"); | |
| } | |
| public static object CreateInstance(string assembly, string fullTypeName) | |
| { | |
| Dictionary<string, Type> typeCache; | |
| if (!_cache.TryGetValue(assembly, out typeCache)) | |
| { | |
| lock (_cache) | |
| { | |
| if (!_cache.TryGetValue(assembly, out typeCache)) | |
| { | |
| typeCache = new Dictionary<string, Type>(); | |
| _cache.Add(assembly, typeCache); | |
| } | |
| } | |
| } | |
| Type t; | |
| if (typeCache.TryGetValue(fullTypeName, out t)) | |
| { | |
| return System.Activator.CreateInstance(t); | |
| } | |
| lock (_cache) | |
| { | |
| if (typeCache.TryGetValue(fullTypeName, out t)) | |
| { | |
| return System.Activator.CreateInstance(t); | |
| } | |
| try | |
| { | |
| if (string.IsNullOrEmpty(AlternativeDllPath)) | |
| { | |
| var ass = assembly; | |
| int loc = -1; | |
| while (!AssemblyExists(ass) && (loc = ass.LastIndexOf(".")) >= 0) | |
| { | |
| ass = ass.Remove(loc); | |
| } | |
| if (loc < 0) | |
| ass = assembly; | |
| var x = System.Activator.CreateInstance(ass, fullTypeName).Unwrap(); | |
| typeCache.Add(fullTypeName, x.GetType()); | |
| return x; | |
| } | |
| else | |
| { | |
| Assembly ass = loadAssemblyFromAlternativePath(assembly); | |
| var x = ass.CreateInstance(fullTypeName); | |
| typeCache.Add(fullTypeName, x.GetType()); | |
| return x; | |
| } | |
| } | |
| catch (FileNotFoundException ex) | |
| { | |
| if (WindowsFormsDesignMode) | |
| return null; | |
| throw new FileNotFoundException(string.Format("Couldn't find assembly \"{0}\"", assembly), ex); | |
| } | |
| catch (Exception ex) | |
| { | |
| if (WindowsFormsDesignMode) | |
| return null; | |
| throw new TypeLoadException("Abstract factory failed to load class '" + fullTypeName + "' in assembly '" + assembly + "'", ex); | |
| } | |
| } | |
| } | |
| public static Assembly loadAssemblyFromAlternativePath(string assembly) | |
| { | |
| if (AlternativeDllPath == null) | |
| return null; | |
| assembly = assembly.Split(',')[0]; | |
| var key = assembly.ToUpper(); | |
| Assembly ass; | |
| if (!_loadedAssemblies.TryGetValue(key, out ass)) | |
| { | |
| lock (_loadedAssemblies) | |
| { | |
| if (!_loadedAssemblies.TryGetValue(key, out ass)) | |
| { | |
| string fileName = null; | |
| fileName = FileExists(assembly); | |
| if (fileName == null && !string.IsNullOrEmpty(AlternativeDllPath)) | |
| fileName = FileExists(Path.Combine(AlternativeDllPath, assembly)); | |
| if (fileName == null && !string.IsNullOrEmpty(AlternativeDllPath2)) | |
| fileName = FileExists(Path.Combine(AlternativeDllPath2, assembly)); | |
| if (fileName == null) | |
| return null; | |
| //throw new FileNotFoundException(); | |
| ass = Assembly.LoadFrom(fileName); | |
| _loadedAssemblies.Add(key, ass); | |
| } | |
| } | |
| } | |
| return ass; | |
| } | |
| public static string AlternativeDllPath { get; set; } | |
| public static string AlternativeDllPath2 { get; set; } | |
| internal static bool WindowsFormsDesignMode { get { return Firefly.Box.UI.Form.FormDesigner.WindowsFormsDesignMode; } } | |
| internal static string FileExists(string name) | |
| { | |
| foreach (var s in new[] { ".dll", ".exe" }) | |
| { | |
| var fullName = name + s; | |
| if (File.Exists(fullName)) | |
| return fullName; | |
| } | |
| return null; | |
| } | |
| static Dictionary<string, Assembly> _loadedAssemblies = new Dictionary<string, Assembly>(); | |
| } | |
| } | 
  
    Sign up for free
    to join this conversation on GitHub.
    Already have an account?
    Sign in to comment