123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569 |
- 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<Assembly> 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;
- };
- }
- /// <summary>
- ///
- /// </summary>
- /// <param name="assemblyFullName">Gets the full name of the assembly, also known as the display name.</param>
- /// <returns></returns>
- 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;
- }
- }
- /// <summary>
- ///
- /// </summary>
- /// <param name="typeFullName">Gets the fully qualified name of the type, including its namespace but not its assembly.</param>
- /// <returns></returns>
- 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<Assembly> 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<object> ctrParameterInstances = new List<object>();
- 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);
- }
- /// <summary>
- /// looped all ctors and could not fit anyone with the deserialized types from ctorInputJsonParameters.
- /// </summary>
- 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<T>(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);
- //}
- /// <summary>
- ///
- /// </summary>
- /// <typeparam name="T">must a concrete type, not interface or abstract</typeparam>
- /// <param name="ctorParametersJsonStr"></param>
- /// <param name="genericTypeParameters"></param>
- /// <param name="dependencies"></param>
- /// <returns></returns>
- public static T Create<T>(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<T>(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<MetaPartsRequired>()?.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<MetaPartsRequired>()?.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<MetaPartsRequired>()?.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 ?? ""));
- }
- }
- }
|