using dnlib.DotNet; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Obfuz.Emit { public interface IGroupByModuleEntity { void Init(ModuleDef mod); } public abstract class GroupByModuleEntityBase : IGroupByModuleEntity { public abstract void Init(ModuleDef mod); } public class GroupByModuleEntityManager { public static GroupByModuleEntityManager Ins { get; private set; } private readonly Dictionary<(ModuleDef, Type), IGroupByModuleEntity> _moduleEmitManagers = new Dictionary<(ModuleDef, Type), IGroupByModuleEntity>(); public static void Reset() { Ins = new GroupByModuleEntityManager(); } public T GetEntity(ModuleDef mod, Func creator = null) where T : IGroupByModuleEntity { var key = (mod, typeof(T)); if (_moduleEmitManagers.TryGetValue(key, out var emitManager)) { return (T)emitManager; } else { T newEmitManager; if (creator != null) { newEmitManager = creator(); } else { newEmitManager = (T)Activator.CreateInstance(typeof(T)); } newEmitManager.Init(mod); _moduleEmitManagers[key] = newEmitManager; return newEmitManager; } } public List GetEntities() where T: IGroupByModuleEntity { var managers = new List(); foreach (var kv in _moduleEmitManagers) { if (kv.Key.Item2 == typeof(T)) { managers.Add((T)kv.Value); } } return managers; } public DefaultMetadataImporter GetDefaultModuleMetadataImporter(ModuleDef module) { return GetEntity(module); } } }