using Edge.Core.Parser.BinaryParser; using Edge.Core.Processor.Communicator; using Edge.Core.Processor.Dispatcher.Attributes; using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text; using System.Text.Json.Serialization; using System.Text.Json; using System.Threading.Tasks; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; namespace Edge.Core.Processor.Dispatcher { public static class ObjectInstanceCreator { public static ILogger mainLogger = Microsoft.Extensions.Logging.Abstractions.NullLogger.Instance; static JsonSerializerOptions jsonSerializerOptions; static string plugInFolder = "plugin"; private static IEnumerable LoadPlugInAssemblies() { //var assemblyFileInfos = new DirectoryInfo(Directory.GetCurrentDirectory()).GetFiles() // .Where(f => f.Extension != null // && (f.Extension.ToLower() == ".dll" || f.Extension.ToLower() == ".exe") // && !f.Name.Contains("Microsoft")); //if (mainLogger.IsEnabled(LogLevel.Trace)) //{ // mainLogger.LogTrace("LoadPlugInAssemblies, root folder(" + Directory.GetCurrentDirectory() + ") loaded assembly files: " + // assemblyFileInfos.Select(fi => fi.Name + ", Length: " + fi.Length + // ", CreationTimeUtc: " + fi.CreationTimeUtc + // ", LastAccessTimeUtc: " + fi.LastAccessTimeUtc + ", LastWriteTimeUtc: " + fi.LastWriteTimeUtc) // .Aggregate(Environment.NewLine, (acc, n) => acc + n + Environment.NewLine)); //} if (Directory.Exists(Directory.GetCurrentDirectory() + "\\" + plugInFolder)) { var plugInFolderAssemblyFileInfos = new DirectoryInfo(Directory.GetCurrentDirectory() + "\\" + plugInFolder).GetFiles() .Where(f => f.Extension != null && (f.Extension.ToLower() == ".dll" || f.Extension.ToLower() == ".exe") && !f.Name.Contains("Microsoft")); if (mainLogger.IsEnabled(LogLevel.Trace)) { mainLogger.LogTrace("LoadPlugInAssemblies, plugIn folder(path: " + plugInFolder + ") contains assembly files: " + plugInFolderAssemblyFileInfos.Select(fi => fi.Name + ", Length: " + fi.Length + ", CreationTimeUtc: " + fi.CreationTimeUtc + ", LastAccessTimeUtc: " + fi.LastAccessTimeUtc + ", LastWriteTimeUtc: " + fi.LastWriteTimeUtc) .Aggregate(Environment.NewLine, (acc, n) => acc + n + Environment.NewLine)); } var rootFolderAssemblyFileInfos = new DirectoryInfo(Directory.GetCurrentDirectory()).GetFiles() .Where(f => f.Extension != null && (f.Extension.ToLower() == ".dll" || f.Extension.ToLower() == ".exe") && !f.Name.Contains("Microsoft")); var plugInFolderDuplicatedFileInfos = plugInFolderAssemblyFileInfos.Join(rootFolderAssemblyFileInfos, fi => fi.Name, fi => fi.Name, (outer, inner) => outer); if (mainLogger.IsEnabled(LogLevel.Information)) { if (plugInFolderDuplicatedFileInfos.Any()) mainLogger.LogInformation("LoadPlugInAssemblies, duplicated PlugIn assembly files found in plugIn folder(path: " + plugInFolder + "): " + plugInFolderDuplicatedFileInfos.Select(fi => fi.Name + ", Length: " + fi.Length + ", CreationTimeUtc: " + fi.CreationTimeUtc + ", LastAccessTimeUtc: " + fi.LastAccessTimeUtc + ", LastWriteTimeUtc: " + fi.LastWriteTimeUtc) .Aggregate(Environment.NewLine, (acc, n) => acc + n + Environment.NewLine) + Environment.NewLine + "Will keep the one in rootFolder which should already loaded into CurrentDomain"); } return plugInFolderAssemblyFileInfos.Where(fi => !plugInFolderDuplicatedFileInfos.Select(dFi => dFi.Name).Contains(fi.Name)) .Select(fi => { try { var ass = Assembly.LoadFrom(fi.FullName); if (mainLogger.IsEnabled(LogLevel.Trace)) { mainLogger.LogTrace("LoadPlugInAssemblies, Loaded assembly by Assembly.LoadFrom: " + fi.FullName); } return ass; } catch (Exception eeee) { mainLogger.LogInformation("LoadPlugInAssemblies, Failed to Loaded assembly by Assembly.LoadFrom: " + fi.FullName + Environment.NewLine + eeee + Environment.NewLine + "Will skip this assembly..."); return null; } }); } else { mainLogger.LogInformation("LoadPlugInAssemblies, failed due to no plugIn folder found"); return null; }; } /// /// /// /// Gets the full name of the assembly, also known as the display name. /// internal static Assembly DefaultSearchLocalAssemblyFileAssemblyResolver(string assemblyFullName, Assembly? requestingAssembly) { try { var targetAssembly = CurrentDomainAssemblies.Where(ass => ass.FullName == assemblyFullName).FirstOrDefault(); if (targetAssembly == null) { if (mainLogger.IsEnabled(LogLevel.Information)) mainLogger.LogInformation("AssemblyResolver, could not resolving: " + assemblyFullName + " from CurrentDomain assemblies" + ", the requestingAssembly is: " + (requestingAssembly?.FullName ?? "") + ", Try loading PlugIn..."); var plugInAssemblies = LoadPlugInAssemblies(); if (plugInAssemblies != null) foreach (var piAss in plugInAssemblies) { if (piAss != null && piAss.FullName == assemblyFullName) { targetAssembly = piAss; break; } } } if (mainLogger.IsEnabled(LogLevel.Information)) if (targetAssembly != null) mainLogger.LogInformation("AssemblyResolver, resolved: " + assemblyFullName + " as assembly: " + (targetAssembly?.FullName ?? "") + ", the requestingAssembly is: " + (requestingAssembly?.FullName ?? "")); else mainLogger.LogInformation("AssemblyResolver, failed for resolving: " + assemblyFullName + ", the requestingAssembly is: " + (requestingAssembly?.FullName ?? "")); return targetAssembly; } catch (Exception eeee) { mainLogger.LogInformation("AssemblyResolver, failed for resolving: " + assemblyFullName + " with exception: " + eeee); return null; } } /// /// /// /// Gets the fully qualified name of the type, including its namespace but not its assembly. /// internal static Type DefaultSearchLocalAssemblyFileTypeResolver(string typeFullName, Assembly? requestingAssembly) { var targetType = CurrentDomainAssemblies.Where(ass => !ass.FullName.Contains("Microsoft")) .SelectMany(a => { Type[] ts = new Type[] { }; try { ts = a.GetTypes(); } catch { } return ts; }).FirstOrDefault(t => t.FullName == typeFullName); if (targetType == null) { if (mainLogger.IsEnabled(LogLevel.Information)) mainLogger.LogInformation("TypeResolver, could not resolving: " + typeFullName + " from CurrentDomain assemblies" + ", the requestingAssembly is: " + (requestingAssembly?.FullName ?? "") + ", Try loading plugIn from folder path: " + plugInFolder); var plugInAssemblies = LoadPlugInAssemblies(); if (plugInAssemblies != null) foreach (var piAss in plugInAssemblies.Where(ass => ass != null)) { try { targetType = piAss.GetTypes().FirstOrDefault(t => t.FullName == typeFullName); if (targetType == null) continue; else break; } catch (Exception eeee) { continue; } } } if (mainLogger.IsEnabled(LogLevel.Information)) if (targetType != null) mainLogger.LogInformation("TypeResolver, resolved: " + typeFullName + " as type: " + (targetType?.FullName ?? "") + " in assembly: " + (targetType?.Assembly?.FullName ?? "") + ", the requestingAssembly is: " + (requestingAssembly?.FullName ?? "")); else mainLogger.LogInformation("TypeResolver, failed for resolving: " + typeFullName + ", the requestingAssembly is: " + (requestingAssembly?.FullName ?? "")); return targetType; } public static IEnumerable CurrentDomainAssemblies { get; private set; } static ObjectInstanceCreator() { var reloadAll_avoid_missing_typesSpecifiedWithoutAssemblyQualifiedName_fi = new DirectoryInfo(Directory.GetCurrentDirectory()).GetFiles() .Where(f => f.Extension != null && (f.Extension.ToLower() == ".dll" || f.Extension.ToLower() == ".exe") && !f.Name.Contains("Microsoft")); foreach (var fi in reloadAll_avoid_missing_typesSpecifiedWithoutAssemblyQualifiedName_fi) { try { //duplicated ass will be auto ignored. var ass = Assembly.LoadFrom(fi.FullName); } catch (Exception eeee) { } } CurrentDomainAssemblies = AppDomain.CurrentDomain.GetAssemblies(); AppDomain.CurrentDomain.TypeResolve += (s, args) => { var type = ObjectInstanceCreator.DefaultSearchLocalAssemblyFileTypeResolver(args.Name, args.RequestingAssembly); return type?.Assembly; }; AppDomain.CurrentDomain.AssemblyResolve += (s, args) => { return DefaultSearchLocalAssemblyFileAssemblyResolver(args.Name, args.RequestingAssembly); }; jsonSerializerOptions = new JsonSerializerOptions() { WriteIndented = true, PropertyNameCaseInsensitive = true, }; jsonSerializerOptions.Converters.Add(new JsonStringEnumConverter()); } public static object Create(string fullTypeStr, Type[] genericTypeParameters, JsonElement[] ctorInputJsonParameters, object[] dependencies) { if (string.IsNullOrEmpty(fullTypeStr)) throw new ArgumentNullException(nameof(fullTypeStr)); var type = Type.GetType(fullTypeStr); if (type == null) throw new InvalidOperationException("Could not get the type for fullTypeStr: " + fullTypeStr); if (type.IsGenericType) if (genericTypeParameters == null || !genericTypeParameters.Any()) throw new InvalidOperationException("Must provide Generic type args for instantiate generic type: " + type.FullName); else type = type.MakeGenericType(genericTypeParameters); var potentialCtors = type.GetConstructors(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); if ((ctorInputJsonParameters?.Length ?? 0) == 0 && (potentialCtors == null || !potentialCtors.Any() || potentialCtors.Any(pct => pct.GetParameters().Length == 0))) return Activator.CreateInstance(type, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, null, null, null); if ((dependencies == null || !dependencies.Any()) && (potentialCtors == null || !potentialCtors.Any())) throw new InvalidOperationException("Can't find constructor with parameter count ==" + (ctorInputJsonParameters?.Length ?? 0) + " for type: " + fullTypeStr); List ctrParameterInstances = new List(); foreach (var ctr in potentialCtors) { int injectedTimes = 0; int nextCtorParameterIndex = 0; for (int i = 0; i < ctr.GetParameters().Length; i++) { var ctrParaInfo = ctr.GetParameters()[i]; try { var part = dependencies?.FirstOrDefault(ip => { if (ip == null) return false; //if (ctrParaInfo.ParameterType.IsGenericType && ctrParaInfo.ParameterType.ge) // return IsAssignableToGenericType(ctrParaInfo.ParameterType, ip.GetType()); var debug = ctrParaInfo.ParameterType; return debug.IsAssignableFrom(ip.GetType()); }); if (part != null) { ctrParameterInstances.Add(part); injectedTimes++; continue; } var ctrParameterInstance = System.Text.Json.JsonSerializer.Deserialize( ctorInputJsonParameters[nextCtorParameterIndex].GetRawText(), ctrParaInfo.ParameterType, jsonSerializerOptions); nextCtorParameterIndex++; ctrParameterInstances.Add(ctrParameterInstance); } catch (Exception exx) { /*any exception indicates the operating ctor is not the expecting one, should try next Ctor*/ ctrParameterInstances.Clear(); break; } } if (ctrParameterInstances.Any() && ctrParameterInstances.Count == (injectedTimes + ctorInputJsonParameters.Length)) { try { var instance = Activator.CreateInstance(type, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, ctrParameterInstances.ToArray(), null, null); return instance; } catch (Exception exx) { throw new InvalidOperationException("CreateInstance caught inner exception for type: " + type.FullName + Environment.NewLine + exx); } } else ctrParameterInstances.Clear(); } throw new JsonConfigNotCompatibleWithAnyCtorDeclarationException(type, null, null, ctorInputJsonParameters); } /// /// looped all ctors and could not fit anyone with the deserialized types from ctorInputJsonParameters. /// public class JsonConfigNotCompatibleWithAnyCtorDeclarationException : Exception { public JsonConfigNotCompatibleWithAnyCtorDeclarationException( Type targetType, ConstructorInfo targetCtor, ParameterInfo targetParameter, JsonElement[] ctorInputJsonParameters) { this.TargetType = targetType; this.TargetCtor = targetCtor; this.TargetParameter = targetParameter; this.CtorInputJsonParameters = ctorInputJsonParameters; } public Type TargetType { get; private set; } public ConstructorInfo TargetCtor { get; private set; } public ParameterInfo TargetParameter { get; private set; } public JsonElement[] CtorInputJsonParameters { get; private set; } } //public static T Create(JsonElement[] ctorParameters, Type[] genericTypeParameters, object[] dependencies) //where T : Type //{ // return (T)Create(typeof(T).FullName, genericTypeParameters, ctorParameters, dependencies); //} //public static bool IsAssignableToGenericType(Type givenType, Type genericType) //{ // var interfaceTypes = givenType.GetInterfaces(); // foreach (var it in interfaceTypes) // { // if (it.IsGenericType && it.GetGenericTypeDefinition() == genericType) // return true; // } // if (givenType.IsGenericType && givenType.GetGenericTypeDefinition() == genericType) // return true; // Type baseType = givenType.BaseType; // if (baseType == null) return false; // return IsAssignableToGenericType(baseType, genericType); //} /// /// /// /// must a concrete type, not interface or abstract /// /// /// /// public static T Create(string ctorParametersJsonStr, Type[] genericTypeParameters, object[] dependencies) //where T : Type { var inputParameter = JsonDocument.Parse(ctorParametersJsonStr).RootElement; JsonElement[] inputParameters = null; if (inputParameter.ValueKind == JsonValueKind.Array) inputParameters = inputParameter.EnumerateArray().ToArray(); else if (inputParameter.ValueKind == JsonValueKind.Object) inputParameters = new JsonElement[] { inputParameter }; else if (inputParameter.ValueKind == JsonValueKind.Undefined) { } else inputParameters = new JsonElement[] { inputParameter }; return (T)Create(typeof(T).FullName, genericTypeParameters, inputParameters, dependencies); } public static object Create(string fullTypeStr, string ctorParametersJsonStr, Type[] genericTypeParameters, object[] dependencies) //where T : Type { if (string.IsNullOrEmpty(ctorParametersJsonStr)) ctorParametersJsonStr = "[]"; var inputParameter = JsonDocument.Parse(ctorParametersJsonStr).RootElement; JsonElement[] inputParameters = null; if (inputParameter.ValueKind == JsonValueKind.Array) inputParameters = inputParameter.EnumerateArray().ToArray(); else if (inputParameter.ValueKind == JsonValueKind.Object) inputParameters = new JsonElement[] { inputParameter }; else if (inputParameter.ValueKind == JsonValueKind.Undefined) { } else inputParameters = new JsonElement[] { inputParameter }; return Create(fullTypeStr, genericTypeParameters, inputParameters, dependencies); } public static T CreateProcessor(ProcessorMetaConfig metaConfig, object[] dependencies) where T : IProcessor { if (metaConfig == null) throw new ArgumentNullException(nameof(metaConfig)); T processorInstance = default(T); if (metaConfig.Parts.Any(p => p.Type == ProcessorMetaPartsTypeEnum.App)) { processorInstance = (T)ObjectInstanceCreator.Create( metaConfig.Parts.First(p => p.Type == ProcessorMetaPartsTypeEnum.App).FullTypeString, null, JsonDocument.Parse(metaConfig.Parts.FirstOrDefault(p => p.Type == ProcessorMetaPartsTypeEnum.App) .ParametersJsonArrayStr ?? "[]").RootElement.EnumerateArray().ToArray(), dependencies); if (processorInstance == null) throw new ArgumentException("Failed for resolving AppProcessor from Type: " + metaConfig.Parts.First(p => p.Type == ProcessorMetaPartsTypeEnum.App).FullTypeString); } else if (metaConfig.Parts.Any(p => p.Type == ProcessorMetaPartsTypeEnum.DeviceHandler)) { var deviceHandlerInstance = ObjectInstanceCreator.Create(metaConfig.Parts.FirstOrDefault(p => p.Type == ProcessorMetaPartsTypeEnum.DeviceHandler).FullTypeString, null, JsonDocument.Parse(metaConfig.Parts.First(p => p.Type == ProcessorMetaPartsTypeEnum.DeviceHandler) .ParametersJsonArrayStr ?? "[]").RootElement.EnumerateArray().ToArray(), dependencies); if (deviceHandlerInstance == null) throw new ArgumentException("Failed for resolving deviceHandlerInstance from Type: " + metaConfig.Parts.FirstOrDefault(p => p.Type == ProcessorMetaPartsTypeEnum.DeviceHandler).FullTypeString); #region Create Parts of RawMessage Type Type rawMessageType = null; if (!string.IsNullOrEmpty(metaConfig?.Parts?.FirstOrDefault(p => p.Type == ProcessorMetaPartsTypeEnum.RawMessageTypeStr)?.FullTypeString)) { rawMessageType = Type.GetType(metaConfig?.Parts?.FirstOrDefault(p => p.Type == ProcessorMetaPartsTypeEnum.RawMessageTypeStr)?.FullTypeString); } else { rawMessageType = deviceHandlerInstance.GetType().GetInterfaces().Where(i => i.Name == typeof(IDeviceHandler<,>).Name).FirstOrDefault()?.GetGenericArguments()?.FirstOrDefault(); } if (rawMessageType == null) throw new ArgumentException("Failed for resolving MetaParts: RawMessageType from Type: " + deviceHandlerInstance.GetType().FullName); #endregion #region Create Parts of Message Type Type messageType = null; if (!string.IsNullOrEmpty(metaConfig?.Parts?.FirstOrDefault(p => p.Type == ProcessorMetaPartsTypeEnum.MessageTypeStr)?.FullTypeString)) { messageType = Type.GetType(metaConfig?.Parts?.FirstOrDefault(p => p.Type == ProcessorMetaPartsTypeEnum.MessageTypeStr)?.FullTypeString); } else { messageType = deviceHandlerInstance.GetType().GetInterfaces().Where(i => i.Name == typeof(IDeviceHandler<,>).Name).FirstOrDefault()?.GetGenericArguments()?.LastOrDefault(); } if (messageType == null) throw new ArgumentException("Failed for resolving MetaParts: MessageType from Type: " + deviceHandlerInstance.GetType().FullName); #endregion #region Create Parts of Parser Instance object parserInstance = null; if (!string.IsNullOrEmpty(metaConfig?.Parts?.FirstOrDefault(p => p.Type == ProcessorMetaPartsTypeEnum.Parser)?.FullTypeString)) { parserInstance = ObjectInstanceCreator.Create(metaConfig.Parts.FirstOrDefault(p => p.Type == ProcessorMetaPartsTypeEnum.Parser).FullTypeString, null, JsonDocument.Parse(metaConfig.Parts.FirstOrDefault(p => p.Type == ProcessorMetaPartsTypeEnum.Parser).ParametersJsonArrayStr ?? "[]").RootElement.EnumerateArray().ToArray(), dependencies); } else { var metaPartsAttri = deviceHandlerInstance.GetType().GetCustomAttributes()?.FirstOrDefault(at => typeof(ParserBase).IsAssignableFrom(at.RequiredPartsType)); if (metaPartsAttri == null) { var searchedParserType = deviceHandlerInstance.GetType().Assembly.GetTypes() .FirstOrDefault(t => typeof(ParserBase).IsAssignableFrom(t)); if (searchedParserType == null) throw new ArgumentException("Failed to Search Parser from Type: " + deviceHandlerInstance.GetType().FullName); else parserInstance = ObjectInstanceCreator.Create(searchedParserType?.AssemblyQualifiedName, null, new JsonElement[] { }, dependencies); } else parserInstance = ObjectInstanceCreator.Create(metaPartsAttri.RequiredPartsType.FullName, null, metaPartsAttri.DefaultCtorParamsJsonStrings.Select(js => JsonDocument.Parse(js).RootElement).ToArray(), //JsonDocument.Parse(metaPartsAttri.DefaultCtorParamsJsonStrings ?? "[]").RootElement.EnumerateArray().ToArray(), dependencies); } if (parserInstance == null) throw new ArgumentException("Failed for resolving Parser from Type: " + deviceHandlerInstance.GetType().FullName); #endregion #region Create Parts of MessageCutter Instance object messageCutterInstance = null; if (!string.IsNullOrEmpty(metaConfig?.Parts?.FirstOrDefault(p => p.Type == ProcessorMetaPartsTypeEnum.MessageCutter)?.FullTypeString)) { messageCutterInstance = ObjectInstanceCreator.Create(metaConfig.Parts.FirstOrDefault(p => p.Type == ProcessorMetaPartsTypeEnum.MessageCutter).FullTypeString, null, JsonDocument.Parse(metaConfig.Parts.FirstOrDefault(p => p.Type == ProcessorMetaPartsTypeEnum.MessageCutter).ParametersJsonArrayStr ?? "[]").RootElement.EnumerateArray().ToArray(), dependencies); } else { var metaPartsAttri = deviceHandlerInstance.GetType().GetCustomAttributes()?.FirstOrDefault(at => at.RequiredPartsType?.GetInterfaces().Any(i => i.Name == typeof(IMessageCutter<>).Name) ?? false); if (metaPartsAttri == null) { var searchedMessageCutterType = deviceHandlerInstance.GetType().Assembly.GetTypes() .FirstOrDefault(t => t.GetInterfaces().Any(i => i.Name == typeof(IMessageCutter<>).Name)); if (searchedMessageCutterType == null) throw new ArgumentException("Failed to Search MessageCutter from Type: " + deviceHandlerInstance.GetType().FullName); else messageCutterInstance = ObjectInstanceCreator.Create(searchedMessageCutterType.AssemblyQualifiedName, null, new JsonElement[] { }, dependencies); } else messageCutterInstance = ObjectInstanceCreator.Create(metaPartsAttri.RequiredPartsType.FullName, null, metaPartsAttri.DefaultCtorParamsJsonStrings.Select(js => JsonDocument.Parse(js).RootElement).ToArray(), dependencies); if (messageCutterInstance == null) throw new ArgumentException("Failed for resolving MessageCutter from Type: " + deviceHandlerInstance.GetType().FullName); } #endregion var communicatorInstance = ObjectInstanceCreator.Create(metaConfig.Parts.FirstOrDefault(p => p.Type == ProcessorMetaPartsTypeEnum.Communicator).FullTypeString, new Type[] { messageType }, JsonDocument.Parse(metaConfig.Parts.FirstOrDefault(p => p.Type == ProcessorMetaPartsTypeEnum.Communicator).ParametersJsonArrayStr ?? "[]").RootElement.EnumerateArray().ToArray(), dependencies.Concat(new object[] { parserInstance, messageCutterInstance }).ToArray()); if (communicatorInstance == null) throw new ArgumentException("Failed for resolving Communicator from Type: " + deviceHandlerInstance.GetType().FullName); #region Create Final Processor Instance if (!string.IsNullOrEmpty(metaConfig?.Parts?.FirstOrDefault(p => p.Type == ProcessorMetaPartsTypeEnum.DeviceProcessor)?.FullTypeString)) { //if (Type.GetType(metaConfig.Parts.First(p => p.Type == ProcessorPartsTypeEnum.Processor).FullTypeString).IsGenericType) //{ processorInstance = (T)ObjectInstanceCreator.Create(metaConfig.Parts.First(p => p.Type == ProcessorMetaPartsTypeEnum.DeviceProcessor).FullTypeString, new Type[] { rawMessageType, messageType }, JsonDocument.Parse(metaConfig.Parts.First(p => p.Type == ProcessorMetaPartsTypeEnum.DeviceProcessor).ParametersJsonArrayStr ?? "[]").RootElement.EnumerateArray().ToArray(), dependencies.Concat(new object[] { parserInstance, messageCutterInstance, communicatorInstance, deviceHandlerInstance }).ToArray()); //} //else //{ // processorInstance = (T)Create(metaConfig.Parts.First(p => p.Type == ProcessorPartsTypeEnum.Processor).FullTypeString, // null, // JsonDocument.Parse(metaConfig.Parts.First(p => p.Type == ProcessorPartsTypeEnum.Processor).ParametersJsonArrayStr ?? "[]").RootElement.EnumerateArray().ToArray(), // parts.Concat(new object[] { parserInstance, messageCutterInstance, communicatorInstance, deviceHandlerInstance }).ToArray()); //} } else { var metaPartsAttri = deviceHandlerInstance.GetType().GetCustomAttributes()?.FirstOrDefault(at => at.RequiredPartsType.GetInterfaces().Any(i => i.Name == typeof(IDeviceProcessor<,>).Name)); if (metaPartsAttri == null) throw new ArgumentException("Failed for resolving MetaParts: DeviceProcessor from Type: " + deviceHandlerInstance.GetType().FullName); processorInstance = (T)ObjectInstanceCreator.Create(metaPartsAttri.RequiredPartsType.FullName, new Type[] { rawMessageType, messageType }, metaPartsAttri.DefaultCtorParamsJsonStrings.Select(js => JsonDocument.Parse(js).RootElement).ToArray(), dependencies.Concat(new object[] { parserInstance, messageCutterInstance, communicatorInstance, deviceHandlerInstance }).ToArray()); } #endregion } if (processorInstance != null) { processorInstance.MetaConfigName = metaConfig.Name; //processorInstance.SerialNumber = Guid.NewGuid().ToString(); return (T)processorInstance; } throw new InvalidOperationException("Can't Create Processor for processorMetaConfig: " + metaConfig.Name + Environment.NewLine + (metaConfig.Description ?? "")); } } }