public async Task <ITemplateCreationResult> InstantiateAsync( ITemplateInfo templateInfo, string?name, string?fallbackName, string?outputPath, IReadOnlyDictionary <string, string?> inputParameters, bool forceCreation = false, string?baselineName = null, bool dryRun = false, CancellationToken cancellationToken = default) { _ = templateInfo ?? throw new ArgumentNullException(nameof(templateInfo)); inputParameters = inputParameters ?? new Dictionary <string, string?>(); cancellationToken.ThrowIfCancellationRequested(); ITemplate?template = LoadTemplate(templateInfo, baselineName); if (template == null) { return(new TemplateCreationResult(CreationResultStatus.NotFound, templateInfo.Name, LocalizableStrings.TemplateCreator_TemplateCreationResult_Error_CouldNotLoadTemplate)); } string?realName = name ?? fallbackName ?? template.DefaultName; if (string.IsNullOrWhiteSpace(realName)) { return(new TemplateCreationResult(CreationResultStatus.MissingMandatoryParam, template.Name, "--name")); } if (template.IsNameAgreementWithFolderPreferred && string.IsNullOrEmpty(outputPath)) { outputPath = name; } string targetDir = !string.IsNullOrWhiteSpace(outputPath) ? outputPath ! : _environmentSettings.Host.FileSystem.GetCurrentDirectory(); Timing contentGeneratorBlock = Timing.Over(_logger, "Template content generation"); try { ICreationResult?creationResult = null; if (!dryRun) { _environmentSettings.Host.FileSystem.CreateDirectory(targetDir); } IComponentManager componentManager = _environmentSettings.Components; // setup separate sets of parameters to be used for GetCreationEffects() and by CreateAsync(). if (!TryCreateParameterSet(template, realName !, inputParameters, out IParameterSet? effectParams, out TemplateCreationResult? resultIfParameterCreationFailed)) { //resultIfParameterCreationFailed is not null when TryCreateParameterSet is false return(resultIfParameterCreationFailed !); } if (effectParams is null) { throw new InvalidOperationException($"{nameof(effectParams)} cannot be null when {nameof(TryCreateParameterSet)} returns 'true'"); } ICreationEffects creationEffects = await template.Generator.GetCreationEffectsAsync( _environmentSettings, template, effectParams, targetDir, cancellationToken).ConfigureAwait(false); IReadOnlyList <IFileChange> changes = creationEffects.FileChanges; IReadOnlyList <IFileChange> destructiveChanges = changes.Where(x => x.ChangeKind != ChangeKind.Create).ToList(); if (!forceCreation && destructiveChanges.Count > 0) { #pragma warning disable CS0618 // Type or member is obsolete if (!_environmentSettings.Host.OnPotentiallyDestructiveChangesDetected(changes, destructiveChanges)) #pragma warning restore CS0618 // Type or member is obsolete { return(new TemplateCreationResult( CreationResultStatus.DestructiveChangesDetected, template.Name, LocalizableStrings.TemplateCreator_TemplateCreationResult_Error_DestructiveChanges, null, null, creationEffects)); } } if (!TryCreateParameterSet(template, realName !, inputParameters, out IParameterSet? creationParams, out resultIfParameterCreationFailed)) { return(resultIfParameterCreationFailed !); } if (creationParams is null) { throw new InvalidOperationException($"{nameof(creationParams)} cannot be null when {nameof(TryCreateParameterSet)} returns 'true'"); } if (!dryRun) { creationResult = await template.Generator.CreateAsync( _environmentSettings, template, creationParams, targetDir, cancellationToken).ConfigureAwait(false); } return(new TemplateCreationResult( status: CreationResultStatus.Success, templateName: template.Name, creationOutputs: creationResult, outputBaseDir: targetDir, creationEffects: creationEffects)); } catch (Exception cx) { string message = string.Join(Environment.NewLine, ExceptionMessages(cx)); return(new TemplateCreationResult( status: cx is TemplateAuthoringException ? CreationResultStatus.TemplateIssueDetected : CreationResultStatus.CreateFailed, templateName: template.Name, localizedErrorMessage: string.Format(LocalizableStrings.TemplateCreator_TemplateCreationResult_Error_CreationFailed, message), outputBaseDir: targetDir)); } finally { #pragma warning disable CS0618 // Type or member is obsolete - temporary until the method becomes internal. ReleaseMountPoints(template); #pragma warning restore CS0618 // Type or member is obsolete contentGeneratorBlock.Dispose(); } }