private static void RunInitializable(IEnumerable<InitializationInfo> list, InitializationInfo init, bool value) { Contract.Requires(list != null); Contract.Requires(init != null); // Prevent duplicate initialization/teardown. if (init.Initialized == value) return; var attr = init.Attribute; var type = init.Method.DeclaringType; var depType = attr.Dependency; if (value && depType != null) { var dep = list.FirstOrDefault(x => x.Method.DeclaringType == depType); if (dep != null) if (!dep.Initialized) RunInitializable(list, dep, true); } if (!value) { var dep = list.FirstOrDefault(x => x.Attribute.Dependency == type); if (dep != null) if (dep.Initialized) RunInitializable(list, dep, false); } var initType = value ? "initialization" : "teardown"; try { init.Method.Invoke(null, new object[] { value }); init.Initialized = value; _log.Info("Completed {0} of {1} successfully.", initType, type.Name); } catch (TargetInvocationException e) { var ex = e.InnerException; _log.Error("Error in {0} of {1}:", initType, init.Attribute.Name); _log.Error("{0}", ex.Message); _log.Error("{0}", ex.StackTrace); } }
/// <summary> /// Initializes all types within an assembly. /// </summary> /// <param name="asm">The assembly to initialize.</param> public static void Initialize(Assembly asm) { Contract.Requires(asm != null); // First, grab all initializable methods... foreach (var type in asm.GetTypes()) { foreach (var method in type.GetMethods(BindingFlags.Public | BindingFlags.Static)) { Contract.Assume(method != null); var attr = method.GetCustomAttribute<InitializableAttribute>(); if (attr == null) continue; if (type.IsGenericType) throw new ReflectionException("Initialization method is within a generic type."); if (!method.IsPublic) throw new ReflectionException("Initialization method must be public."); if (method.IsGenericMethod) throw new ReflectionException("Initialization method must not be generic."); if (method.ReturnType != typeof(void)) throw new ReflectionException("Invalid initialization method return type."); var param = method.GetParameters(); if (param.Length != 1) throw new ReflectionException("Invalid initialization method parameter count."); if (param[0].ParameterType != typeof(bool)) throw new ReflectionException("Invalid initialization method parameter type."); var init = new InitializationInfo(attr, method); var pass = attr.Pass; if (!_initializers.ContainsKey(pass)) _initializers[pass] = new List<InitializationInfo>(); _initializers[pass].Add(init); } } }