Example #1
0
        /// <summary>
        /// Retrieves all depending modules of the specified module recursively and checks for circular dependencies.
        /// </summary>
        /// <param name="module">Code generation module to retrieve depending modules for.</param>
        /// <param name="alreadyProcessedModules">Modules that have already been processed.</param>
        /// <returns>Code generation modules that depend on the specified module.</returns>
        private static HashSet <ICodeGenModule> GetDependingModules(ICodeGenModule module, HashSet <ICodeGenModule> alreadyProcessedModules)
        {
            HashSet <ICodeGenModule> complete = new HashSet <ICodeGenModule>(IdentityComparer <ICodeGenModule> .Default);

            // add all modules the current module depends on and check for circular dependencies
            foreach (ICodeGenModule dependency in module.Dependencies)
            {
                // check whether the depending module has already been processed, which would indicate a circular dependency
                if (alreadyProcessedModules.Contains(dependency, IdentityComparer <ICodeGenModule> .Default))
                {
                    string error = string.Format("Module ({0}) is referenced circularly.", dependency.ToString());
                    throw new CodeGenException(error);
                }

                // add the current module to the 'processed' set to indicate that it is already part of the dependency chain
                // (depending module may not reference a module already listed there => circular dependency check)
                HashSet <ICodeGenModule> processed = new HashSet <ICodeGenModule>(alreadyProcessedModules, IdentityComparer <ICodeGenModule> .Default)
                {
                    dependency
                };

                // resolve dependencies and merge depending modules into the complete set of modules taking part
                HashSet <ICodeGenModule> dependencies = GetDependingModules(dependency, processed);
                complete.UnionWith(dependencies);
                complete.Add(dependency);
            }

            return(complete);
        }
Example #2
0
        /// <summary>
        /// Adds a code generation module contributing to the type to create.
        /// </summary>
        /// <param name="module">Module to add.</param>
        public void AddModule(ICodeGenModule module)
        {
            if (module == null)
            {
                throw new ArgumentNullException(nameof(module));
            }
            if (mSortedModules.Find(other => object.ReferenceEquals(other, module)) != null)
            {
                throw new CodeGenException("The specified module is already part of the type definition.");
            }

            // update list of modules
            // (ResolveModuleDependencies() can throw CodeGenException, if it detects a circular module dependency)
            List <ICodeGenModule> modules = new List <ICodeGenModule>(mSortedModules);

            modules.Add(module);
            mSortedModules = new List <ICodeGenModule>(ResolveModuleDependencies(modules));
        }