private IEnumerable <Type> GetTypesWithScraperSettingsAttribute(Assembly assembly) { foreach (Type type in assembly.GetTypes()) { if (type.GetCustomAttributes(typeof(InjectorSettings), true).Length > 0) { InjectorSettings attrib = type.GetCustomAttribute <InjectorSettings>(); if (attrib.RunAtStart == true) { yield return(type); } } } }
public void CreateInstances() { Injectors = new List <BaseInjector>(); var assemblies = AppDomain.CurrentDomain.GetAssemblies(); var allClasses = new List <Type>(); foreach (var assembly in assemblies) { var classes = GetTypesWithScraperSettingsAttribute(assembly).ToList <Type>(); allClasses.AddRange(classes); } foreach (var item in allClasses) { var classType = (BaseInjector)Activator.CreateInstance(item); Injectors.Add(classType); classType.JavascriptInjectService = this; //classType.Browser = new WebBrowser(); InjectorSettings settings = classType.GetType().GetCustomAttribute <InjectorSettings>(); classType.Name = settings.Name; if (!String.IsNullOrEmpty(settings.Url)) { classType.Url = settings.Url; } var t = new Thread(() => CreateBrowser(classType)); t.SetApartmentState(ApartmentState.STA); t.Start(); while (classType.DoneLoading == false) { } //classType.BrowserForm.Hide(); classType.Init(); } }
public InjectorTypeNameInfo(Type type, string name, InjectorSettings settings) { Type = type; InstantiableName = name; Instantiable definition = null; #region Definitions if (type.IsInterface) { definition = settings.GetInterfaceInstanceDefinition(type.AssemblyQualifiedName, name); } else if (type.IsAbstract) { definition = settings.GetAbstractInstanceDefinition(type.AssemblyQualifiedName, name); } else if (type.IsClass) { definition = settings.GetInstantiableClassDefinition(type.AssemblyQualifiedName).FirstOrDefault(i => i.Name == name); if (definition == null) { definition = new Instantiable { Type = type.AssemblyQualifiedName, Name = name } } ; } Definition = definition; #endregion Singleton = definition.Singleton; var defType = Core.GetType(definition.Type, true); if (defType is null) { return; } InstantiableType = defType; ConstructorInfo selectedCtor = null; #region Constructor Selector var ctors = defType.GetConstructors(); if (definition.Parameters == null || definition.Parameters.Count == 0) { #region .ctor Selector var lstParams = new List <string>(); var ctorsOrdersByParamLength = ctors.OrderByDescending(i => i.GetParameters().Length); foreach (var ctor in ctorsOrdersByParamLength) { selectedCtor = ctor; var ctorParameters = ctor.GetParameters(); foreach (var ctorParam in ctorParameters) { var paramType = ctorParam.ParameterType; var paramTypeAQName = paramType.AssemblyQualifiedName; if (ctorParam.HasDefaultValue) { continue; } if (paramType.IsInterface && settings.GetInterfaceDefinition(paramTypeAQName) == null) { selectedCtor = null; lstParams.Add($"A definition for interface: '{paramTypeAQName}' wasn't found."); break; } else if (paramType.IsAbstract && settings.GetAbstractDefinition(paramTypeAQName) == null) { selectedCtor = null; lstParams.Add($"A definition for abstract: '{paramTypeAQName}' wasn't found."); break; } else if (paramType.IsClass && !settings.GetInstantiableClassDefinition(paramTypeAQName).Any()) { selectedCtor = null; lstParams.Add($"A definition for class: '{paramTypeAQName}' wasn't found."); break; } } if (selectedCtor != null) { break; } } #endregion if (selectedCtor == null) { throw new Exception($"A valid .ctor wasn't found in the type: {defType.AssemblyQualifiedName}.\r\n{lstParams.Join("\r\n")}"); } } else { selectedCtor = ctors.FirstOrDefault(c => { var cParams = c.GetParameters(); var definitionParameters = definition.Parameters.ToDictionary(k => k.Name); foreach (var cParam in cParams) { if (!definitionParameters.Remove(cParam.Name)) { if (!cParam.HasDefaultValue) { return(false); } } } return(definitionParameters.Count == 0); }); if (selectedCtor == null) { throw new Exception($"A .ctor with {definition.Parameters.Count} parameters wasn't found in the type: {defType.AssemblyQualifiedName}."); } } #endregion #region Create Expression var serExpressions = new List <Expression>(); var varExpressions = new List <ParameterExpression>(); var value = Expression.Parameter(defType, "value"); varExpressions.Add(value); var returnTarget = Expression.Label(typeof(object), "ReturnTarget"); #region New Call var paramExpressions = new List <Expression>(); var cParameters = selectedCtor.GetParameters(); var defParameters = definition.Parameters.ToDictionary(k => k.Name); foreach (var cParam in cParameters) { if (defParameters.TryGetValue(cParam.Name, out var defParam)) { Argument defArgument = defParam; if (!string.IsNullOrWhiteSpace(defParam.ArgumentName)) { settings.Arguments.TryGet(defParam.ArgumentName, out defArgument); } switch (defArgument.Type) { case ArgumentType.Abstract: case ArgumentType.Instance: case ArgumentType.Interface: paramExpressions.Add( Expression.Convert( Expression.Call( Expression.Property(null, typeof(Core), "Injector"), "New", null, Expression.Constant(Core.GetType(defArgument.Value), typeof(Type)), Expression.Constant(defArgument.ClassName, typeof(string))), cParam.ParameterType) ); break; case ArgumentType.Raw: var rawValue = defArgument.Value.ParseTo(cParam.ParameterType, cParam.ParameterType.IsValueType ? System.Activator.CreateInstance(cParam.ParameterType) : null); paramExpressions.Add(Expression.Constant(rawValue, cParam.ParameterType)); break; case ArgumentType.Settings: if (Core.Settings.TryGet(defArgument.Value, out var setKeyValue)) { var setValue = setKeyValue.Value.ParseTo(cParam.ParameterType, cParam.ParameterType.IsValueType ? System.Activator.CreateInstance(cParam.ParameterType) : null); paramExpressions.Add(Expression.Constant(setValue, cParam.ParameterType)); } else { paramExpressions.Add(Expression.Constant(cParam.ParameterType.IsValueType ? System.Activator.CreateInstance(cParam.ParameterType) : null, cParam.ParameterType)); } break; } } else if (cParam.HasDefaultValue) { paramExpressions.Add(Expression.Constant(cParam.RawDefaultValue, cParam.ParameterType)); } } if (paramExpressions.Count == 0) { serExpressions.Add(Expression.Assign(value, Expression.New(selectedCtor))); } else { serExpressions.Add(Expression.Assign(value, Expression.New(selectedCtor, paramExpressions))); } #endregion #region Properties Set if (definition.PropertiesSets?.Any() == true) { foreach (var set in definition.PropertiesSets) { Argument argSet = set; if (!string.IsNullOrWhiteSpace(set.ArgumentName)) { settings.Arguments.TryGet(set.ArgumentName, out argSet); } var property = defType.GetProperty(set.Name, BindingFlags.Instance | BindingFlags.Public); if (property == null) { throw new Exception($"The Property '{set.Name}' can't be found in the object type '{definition.Type}'"); } var propertyExpression = Expression.Property(value, property); switch (argSet.Type) { case ArgumentType.Abstract: case ArgumentType.Instance: case ArgumentType.Interface: serExpressions.Add( Expression.Assign(propertyExpression, Expression.Convert( Expression.Call( Expression.Property(null, typeof(Core), "Injector"), "New", null, Expression.Constant(Core.GetType(argSet.Value), typeof(Type)), Expression.Constant(argSet.ClassName, typeof(string))), property.PropertyType) ) ); break; case ArgumentType.Raw: var rawValue = argSet.Value.ParseTo(property.PropertyType, property.PropertyType.IsValueType ? System.Activator.CreateInstance(property.PropertyType) : null); serExpressions.Add(Expression.Assign(propertyExpression, Expression.Constant(rawValue, property.PropertyType))); break; case ArgumentType.Settings: if (Core.Settings.TryGet(argSet.Value, out var setKeyValue)) { var setValue = setKeyValue.Value.ParseTo(property.PropertyType, property.PropertyType.IsValueType ? System.Activator.CreateInstance(property.PropertyType) : null); serExpressions.Add(Expression.Assign(propertyExpression, Expression.Constant(setValue, property.PropertyType))); } else { serExpressions.Add(Expression.Assign(propertyExpression, Expression.Constant(property.PropertyType.IsValueType ? System.Activator.CreateInstance(property.PropertyType) : null, property.PropertyType))); } break; } } } #endregion serExpressions.Add(Expression.Return(returnTarget, value, typeof(object))); serExpressions.Add(Expression.Label(returnTarget, value)); var block = Expression.Block(varExpressions, serExpressions).Reduce(); var lambda = Expression.Lambda <Func <object> >(block, type.Name + "_Activator", null); ActivatorExpression = lambda; Activator = lambda.Compile(); #endregion ActivatorByExpression = true; if (Singleton) { SingletonValue = Activator(); SettedSingletonValue = true; } }