예제 #1
0
        /// <summary>
        /// Loads the carrier dictionary from the specified assembly.
        /// </summary>
        /// <param name="assembly">The assembly to consider.</param>
        /// <param name="extensionDefinition">The extension definition to consider.</param>
        /// <param name="log">The log to consider.</param>
        /// <returns></returns>
        private int LoadCarrierDictionaryFromAssembly(
            Assembly assembly,
            IBdoExtensionDefinition extensionDefinition,
            IBdoLog log = null)
        {
            if (assembly == null)
            {
                return(-1);
            }

            // we load the carrier dictionary from the assembly

            IBdoCarrierDictionaryDto dictionaryDto = (IBdoCarrierDictionaryDto)ExtractDictionaryFromAssembly <BdoCarrierDefinitionDto>(assembly, log);

            // we feach carrier classes

            var types = assembly.GetTypes().Where(p => typeof(IBdoCarrier).IsAssignableFrom(p) && !p.IsAbstract);
            int count = 0;

            foreach (Type type in types)
            {
                IBdoCarrierDefinitionDto definitionDto = new BdoCarrierDefinitionDto();

                // we update definition from carrier attribute

                if (type.GetCustomAttribute(typeof(BdoCarrierAttribute)) is BdoCarrierAttribute carrierAttribute)
                {
                    UpdateDictionary(definitionDto, carrierAttribute);
                }
                definitionDto.ItemClass = type.FullName;
                definitionDto.LibraryId = extensionDefinition?.Dto?.Id;

                // we create the detail specification from detail property attributes

                foreach (PropertyInfo property in type.GetProperties().Where(p => p.GetCustomAttributes(typeof(DetailPropertyAttribute)).Any()))
                {
                    definitionDto.DetailSpec.Add(ElementSpecFactory.Create(property.Name, property.PropertyType));
                }

                // we build the runtime definition

                IBdoCarrierDefinition itemDefinition = new BdoCarrierDefinition(extensionDefinition, definitionDto)
                {
                    RuntimeType = type
                };

                if (dictionaryDto != null)
                {
                    // retrieve the definition index

                    // update definition with index
                }

                _store.Add <IBdoCarrierDefinition>(itemDefinition);

                count++;
            }

            return(count);
        }
        /// <summary>
        /// Extract extension definition from the specified assembly.
        /// </summary>
        /// <param name="assembly">The assembly to consider.</param>
        /// <param name="resourceFullName">The full name of the resouce to consider.</param>
        /// <param name="log">The log to consider.</param>
        /// <returns>The created library.</returns>
        private IBdoExtensionDefinition ExtractExtensionDefinition(
            Assembly assembly,
            string resourceFullName = null,
            IBdoLog log             = null)
        {
            IBdoExtensionDefinition definition = null;

            if (assembly != null)
            {
                if (resourceFullName == null)
                {
                    resourceFullName = Array.Find(
                        assembly.GetManifestResourceNames(), p => p.EndsWith(__DefaultResourceFileName, StringComparison.OrdinalIgnoreCase));
                }

                Stream stream = null;
                if (resourceFullName == null)
                {
                    log?.AddError("Could not find any library definition in assembly (default named '" + __DefaultResourceFileName.ToLower() + "')");
                }
                else
                {
                    try
                    {
                        stream = assembly.GetManifestResourceStream(resourceFullName);
                        if (stream == null)
                        {
                            log?.AddError("Could not find the library definition named '" + resourceFullName + "' in assembly");
                        }
                        else
                        {
                            IBdoExtensionDefinitionDto definitionDto = null;
                            XmlSerializer serializer = new XmlSerializer(typeof(BdoExtensionDefinitionDto));
                            definitionDto = (BdoExtensionDefinitionDto)serializer.Deserialize(stream);
                            definitionDto?.Initialize();

                            definition = new BdoExtensionDefinition(definitionDto);
                        }
                    }
                    catch (Exception ex)
                    {
                        log?.AddException(ex);
                    }
                    finally
                    {
                        stream?.Close();
                    }
                }
            }

            return(definition);
        }
        /// <summary>
        /// Loads the routine dictionary from the specified assembly.
        /// </summary>
        /// <param name="assembly">The assembly to consider.</param>
        /// <param name="extensionDefinition">The extension definition to consider.</param>
        /// <param name="log">The log to consider.</param>
        /// <returns></returns>
        private int LoadRoutineDictionaryFromAssembly(
            Assembly assembly,
            IBdoExtensionDefinition extensionDefinition,
            IBdoLog log = null)
        {
            if (assembly == null)
            {
                return(-1);
            }

            // we feach routine classes

            int count = 0;

            return(count);
        }
        /// <summary>
        /// Loads the extension dictionary of the specified kind from the specified assembly.
        /// </summary>
        /// <param name="assembly">The assembly to consider.</param>
        /// <param name="kind">The kind of item to consider.</param>
        /// <param name="extensionDefinition">The extension definition to consider.</param>
        /// <param name="log">The log to consider.</param>
        /// <returns></returns>
        private int LoadDictionary(
            Assembly assembly,
            BdoExtensionItemKind kind,
            IBdoExtensionDefinition extensionDefinition = null,
            IBdoLog log = null)
        {
            if (assembly == null)
            {
                return(-1);
            }

            switch (kind)
            {
            case BdoExtensionItemKind.Carrier:
                return(LoadCarrierDictionaryFromAssembly(assembly, extensionDefinition, log));

            case BdoExtensionItemKind.Connector:
                return(LoadConnectorDictionaryFromAssembly(assembly, extensionDefinition, log));

            case BdoExtensionItemKind.Entity:
                return(LoadEntityDictionaryFromAssembly(assembly, extensionDefinition, log));

            case BdoExtensionItemKind.Format:
                return(LoadFormatDictionaryFromAssembly(assembly, extensionDefinition, log));

            case BdoExtensionItemKind.Handler:
                return(LoadHandlerDictionaryFromAssembly(assembly, extensionDefinition, log));

            case BdoExtensionItemKind.Metrics:
                return(LoadMetricsDictionaryFromAssembly(assembly, extensionDefinition, log));

            case BdoExtensionItemKind.Routine:
                return(LoadRoutineDictionaryFromAssembly(assembly, extensionDefinition, log));

            case BdoExtensionItemKind.Scriptword:
                return(LoadScripwordDictionaryFromAssembly(assembly, extensionDefinition, log));

            case BdoExtensionItemKind.Task:
                return(LoadTaskDictionaryFromAssembly(assembly, extensionDefinition, log));

            case BdoExtensionItemKind.Any:
            case BdoExtensionItemKind.None:
                break;
            }
            return(-1);
        }
        /// <summary>
        /// Loads the script word dictionary from the specified assembly.
        /// </summary>
        /// <param name="assembly">The assembly to consider.</param>
        /// <param name="extensionDefinition">The extension definition to consider.</param>
        /// <param name="log">The log to consider.</param>
        /// <returns></returns>
        private int LoadScripwordDictionaryFromAssembly(
            Assembly assembly,
            IBdoExtensionDefinition extensionDefinition,
            IBdoLog log = null)
        {
            if (assembly == null)
            {
                return(-1);
            }

            // we load the carrier dictionary from the assembly

            IBdoScriptwordDictionaryDto dictionaryDto = (IBdoScriptwordDictionaryDto)ExtractDictionaryFromAssembly <BdoScriptwordDefinitionDto>(assembly, log);

            // we define definitions

            int count = 0;

            if (dictionaryDto == null)
            {
                log?.AddWarning(title: "No script word dictionary was found");
            }
            else
            {
                List <BdoScriptwordDefinition> scriptwordDefinitions = new List <BdoScriptwordDefinition>();

                var types = assembly.GetTypes().Where(p => p.GetCustomAttributes(typeof(BdoScriptwordDefinitionAttribute)).Any());
                foreach (Type type in types)
                {
                    // we feach methods
                    var methodInfos = type.GetMethods(BindingFlags.Public | BindingFlags.Static);
                    foreach (MethodInfo methodInfo in methodInfos)
                    {
                        if (methodInfo.GetCustomAttribute(typeof(BdoScriptwordAttribute)) is BdoScriptwordAttribute scriptWordAttribute)
                        {
                            // we determine the name of the definition

                            string definitionName = scriptWordAttribute.Name;

                            // we update the definition with the dictionary if there is one

                            if (dictionaryDto != null)
                            {
                                IBdoScriptwordDefinitionDto definitionDto = dictionaryDto.GetDefinition(definitionName, methodInfo.Name);

                                if (definitionDto == null)
                                {
                                    log?.AddError(title: "Script word '" + methodInfo.Name + "' not found in dictionary");
                                }
                                else
                                {
                                    definitionDto.CallingClass = type.FullName;
                                    definitionDto.LibraryId    = extensionDefinition?.Dto?.Id;

                                    // we create the runtime definition

                                    BdoScriptwordDefinition itemDefinition = new BdoScriptwordDefinition(extensionDefinition, definitionDto);

                                    try
                                    {
                                        if (methodInfo.GetParameters().Length == 0)
                                        {
                                            itemDefinition.RuntimeBasicFunction += methodInfo.CreateDelegate(
                                                typeof(BdoScriptwordBasicDelegare)) as BdoScriptwordBasicDelegare;
                                        }
                                        else
                                        {
                                            itemDefinition.RuntimeScopedFunction += methodInfo.CreateDelegate(
                                                typeof(BdoScriptwordScopedDelegate)) as BdoScriptwordScopedDelegate;
                                        }

                                        scriptwordDefinitions.Add(itemDefinition);

                                        count++;
                                    }
                                    catch (ArgumentException)
                                    {
                                        log?.AddError(
                                            title: "Incompatible function ('" + methodInfo.Name + "')",
                                            description: "Function '" + definitionDto.RuntimeFunctionName + "' in class '" + definitionDto.CallingClass + "' has inexpected parameters.");
                                    }
                                }
                            }
                        }
                    }
                }

                // we build the script word tree

                BuildScriptwordTree(dictionaryDto, scriptwordDefinitions, log);
            }

            return(count);
        }
예제 #6
0
        /// <summary>
        /// Loads the task dictionary from the specified assembly.
        /// </summary>
        /// <param name="assembly">The assembly to consider.</param>
        /// <param name="extensionDefinition">The extension definition to consider.</param>
        /// <param name="log">The log to consider.</param>
        /// <returns></returns>
        private int LoadTaskDictionaryFromAssembly(
            Assembly assembly,
            IBdoExtensionDefinition extensionDefinition,
            IBdoLog log = null)
        {
            if (assembly == null)
            {
                return(-1);
            }

            // we load the carrier dictionary from the assembly

            IBdoTaskDictionaryDto dictionaryDto = (IBdoTaskDictionaryDto)ExtractDictionaryFromAssembly <BdoTaskDefinitionDto>(assembly, log);

            // we feach task classes

            int count = 0;

            var types = assembly.GetTypes().Where(p => typeof(IBdoTask).IsAssignableFrom(p));

            foreach (Type type in types)
            {
                IBdoTaskDefinitionDto definitionDto = new BdoTaskDefinitionDto();

                if (type.GetCustomAttributes(typeof(BdoTaskAttribute)).FirstOrDefault() is BdoTaskAttribute taskAttribute)
                {
                    UpdateDictionary(definitionDto, taskAttribute);
                }
                definitionDto.ItemClass = type.FullName;
                definitionDto.LibraryId = extensionDefinition?.Dto?.Id;

                foreach (PropertyInfo property in type.GetProperties().Where(p => p.GetCustomAttributes(typeof(TaskInputAttribute)).Any()))
                {
                    definitionDto.InputSpecification.Add(ElementSpecFactory.Create(property.Name, property.PropertyType));
                }

                foreach (PropertyInfo property in type.GetProperties().Where(p => p.GetCustomAttributes(typeof(TaskOutputAttribute)).Any()))
                {
                    definitionDto.OutputSpecification.Add(ElementSpecFactory.Create(property.Name, property.PropertyType));
                }

                // we build the runtime definition

                IBdoTaskDefinition itemDefinition = new BdoTaskDefinition(extensionDefinition, definitionDto)
                {
                    RuntimeType = type
                };

                if (dictionaryDto != null)
                {
                    // retrieve the definition index

                    // update definition with index
                }

                _store.Add <IBdoTaskDefinition>(itemDefinition);

                count++;
            }

            return(count);
        }
예제 #7
0
        /// <summary>
        /// Loads the specified library.
        /// </summary>
        /// <param name="libraryReference">The library reference to consider.</param>
        /// <returns>Returns the loaded library.</returns>
        private IBdoLog LoadLibrary(IBdoAssemblyReference libraryReference)
        {
            var log = new BdoLog();

            if (libraryReference != null && _loadOptions?.SourceKinds != null)
            {
                try
                {
                    Assembly assembly = null;

                    // first we load the assembly

                    IBdoLog firstLog = new BdoLog()
                    {
                        DisplayName = "Loading library '" + libraryReference.Name + "'"
                    };

                    foreach (DatasourceKind dataSourceKind in _loadOptions?.SourceKinds)
                    {
                        IBdoLog subLog = firstLog.AddSubLog(title: "Loading assembly from '" + dataSourceKind.ToString() + "'", eventKind: EventKinds.Message);

                        switch (dataSourceKind)
                        {
                        case DatasourceKind.Memory:
                            if (!string.IsNullOrEmpty(libraryReference.Name))
                            {
                                assembly = AppDomainPool.LoadAssembly(_appDomain, libraryReference.Name, subLog);
                            }
                            else
                            {
                                subLog?.AddWarning("File name missing");
                            }
                            break;

                        case DatasourceKind.Repository:
                            string fileName = libraryReference.FileName;
                            if (string.IsNullOrEmpty(fileName))
                            {
                                fileName = libraryReference.Name + ".dll";
                            }

                            string filePath = _loadOptions.LibraryFolderPath.EndingWith(@"\").ToPath() + fileName;
                            if (!File.Exists(filePath))
                            {
                                subLog?.AddError("Could not find the assembly file path '" + filePath + "'");
                            }
                            else
                            {
                                assembly = AppDomainPool.LoadAssemblyFromFile(_appDomain, filePath, subLog);

                                if (assembly == null)
                                {
                                    subLog?.AddError("Could not load assembly '" + filePath + "'");
                                }
                                else
                                {
                                    subLog?.AddCheckpoint("Loading assembly from file '" + filePath + "'");
                                    assembly = Assembly.LoadFrom(filePath);
                                }
                            }
                            break;

                        case DatasourceKind.RestApi:
                            break;
                        }

                        if (assembly != null)
                        {
                            subLog?.AddMessage("Assembly loaded");
                            break;
                        }
                    }

                    // if we have an assembly then we index library items

                    if (assembly == null)
                    {
                        log?.AddSubLog(firstLog, p => p.HasErrorsOrExceptionsOrWarnings());
                    }
                    else
                    {
                        firstLog.GetEvents(true, EventKinds.Error, EventKinds.Exception).ForEach(p => p.Kind = EventKinds.Warning);
                        log?.AddSubLog(firstLog);

                        // we get the extension definition

                        IBdoExtensionDefinition extensionDefinition = ExtractExtensionDefinition(assembly, null, log);

                        // we load the using assemblies

                        if (extensionDefinition?.Dto?.UsingAssemblyFileNames != null)
                        {
                            foreach (var st in extensionDefinition.Dto.UsingAssemblyFileNames)
                            {
                                var fileName = st;
                                if (!fileName.EndsWith(".dll", StringComparison.OrdinalIgnoreCase))
                                {
                                    fileName += ".dll";
                                }
                                IBdoAssemblyReference reference = BdoAssemblyReferenceFactory.Create(st).WithFileName(fileName);

                                log.AddSubLog(LoadExtensionsInStore(reference), title: "Loading using extensions...");
                            }
                        }

                        // we load the item definition specifiying the extension definition

                        foreach (BdoExtensionItemKind kind in new[] {
                            BdoExtensionItemKind.Carrier,
                            BdoExtensionItemKind.Connector,
                            BdoExtensionItemKind.Entity,
                            BdoExtensionItemKind.Handler,
                            BdoExtensionItemKind.Metrics,
                            BdoExtensionItemKind.Routine,
                            BdoExtensionItemKind.Scriptword,
                            BdoExtensionItemKind.Task
                        })
                        {
                            IBdoLog subSubLog = new BdoLog();
                            int     count     = LoadDictionary(assembly, kind, extensionDefinition, subSubLog);

                            if (subSubLog.HasErrorsOrExceptionsOrWarnings())
                            {
                                log.AddSubLog(
                                    subSubLog,
                                    title: "Dictionary '" + kind.ToString() + "' loaded (" + count.ToString() + " items added)");
                            }
                            else
                            {
                                log.AddMessage("Dictionary '" + kind.ToString() + "' loaded (" + count.ToString() + " items added)");
                            }
                        }
                    }
                }
                catch (Exception exception)
                {
                    log?.AddException(exception);
                }
            }

            return(log);
        }