protected override void Dispose(bool disposing) { base.Dispose(disposing); if (this.templateScope != null) { this.templateScope.Dispose(); this.templateScope = null; } if (this.eventBufferingScope != null) { this.eventBufferingScope.Dispose(); this.eventBufferingScope = null; } }
internal static IItemContainer UnfoldTemplate(ISolution solution, IUriReferenceService uriService, IServiceProvider serviceProvider, IProductElement owner, UnfoldVsTemplateSettings settings, bool fromWizard) { var eventScope = new StoreEventBufferingScope(); try { Guard.NotNull(() => solution, solution); Guard.NotNull(() => owner, owner); Guard.NotNull(() => settings, settings); var pathHelper = new UnfoldPathHelper(solution); var templateUri = new Uri(settings.TemplateUri); // Resolve the designtime template tracer.Verbose( Resources.UnfoldVsTemplateCommand_TraceResolvingTemplateUri, owner, settings.TemplateUri.ToString()); var template = uriService.TryResolveUri<ITemplate>(templateUri); if (template == null) { throw new FileNotFoundException( string.Format(CultureInfo.CurrentCulture, Resources.UnfoldVsTemplateCommand_ErrorTemplateNotFound, templateUri), settings.TemplateUri.ToString()); } // Resolve the vstemplate tracer.Verbose( Resources.UnfoldVsTemplateCommand_TraceResolvingVsTemplateUri, owner, templateUri); var vsTemplate = uriService.ResolveUri<IVsTemplate>(templateUri); // Get the resolved instance name for the unfolded item var unfoldResolver = new UnfoldParentResolver(solution, uriService, owner, vsTemplate); unfoldResolver.ResolveParent(settings.TargetPath, settings.TargetFileName); var instanceName = unfoldResolver.FileName; if (settings.SanitizeName) { instanceName = DataFormats.MakePreferredSolutionItemName(instanceName); } // Ensure name is unique (on disk) var solutionItemName = pathHelper.GetUniqueName(instanceName, vsTemplate, unfoldResolver.ParentItem); //TODO: We need to close the existing solution (if any) if template is a ProjectGroup // if (vsTemplate.Type == VsTemplateType.ProjectGroup). // Otherwise this will fail the unfold // Unfold the template var generatedItem = template.Unfold(unfoldResolver.ResolveExtension(solutionItemName), unfoldResolver.ParentItem); eventScope.Dispose(); // Perhaps the template unfolded multiple items and none was identifed as the primary // (such as in a multi-item item template, with no non-fixed named items) if (generatedItem != null) { // Prompt user to update element instance name (on name collision) if he is synching names, // it doesn't make sense to correlate them otherwise if (settings.SyncName) { if (!instanceName.Equals(solutionItemName, StringComparison.OrdinalIgnoreCase)) { if (serviceProvider != null) { var shellService = serviceProvider.GetService<IVsUIShell>(); if (shellService != null) { var result = shellService.ShowPrompt( Resources.UnfoldVsTemplateCommand_PromptToSyncNameTitle, string.Format(CultureInfo.CurrentCulture, Resources.UnfoldVsTemplateCommand_PromptToSyncName, instanceName, solutionItemName)); if (result) { owner.InstanceName = solutionItemName; } } else { owner.InstanceName = solutionItemName; } } else { owner.InstanceName = solutionItemName; } } } if (!fromWizard) { tracer.Info( Resources.UnfoldVsTemplateCommand_TraceAddReference, owner); SolutionArtifactLinkReference .AddReference(owner, uriService.CreateUri(generatedItem)) .Tag = BindingSerializer.Serialize(new ReferenceTag { Tag = settings.Tag ?? string.Empty, SyncNames = settings.SyncName, TargetFileName = settings.TargetFileName }); } } return generatedItem; } catch (WizardBackoutException) //cancel the unfold if wizard backout { tracer.Info( Resources.UnfoldVsTemplateCommand_TraceWizardCancelled); owner.Delete(); eventScope.Dispose(); return null; } catch (COMException comEx) { tracer.Error( comEx, Resources.UnfoldVsTemplateCommand_TraceCOMException, owner.InstanceName, settings.TemplateUri); owner.Delete(); eventScope.Dispose(); throw; } catch (OperationCanceledException) { // This exception can be throw explicitly by author code // that wishes to cancel execution, with a friendly user // message, so we can pass this on as-is. throw; } catch (Exception ex) //cancel the unfold if another unexpected exception happened { tracer.Info( Resources.UnfoldVsTemplateCommand_TraceUnexpectedException, owner.InstanceName, settings.TemplateUri); owner.Delete(); eventScope.Dispose(); throw new OperationCanceledException(string.Format( CultureInfo.CurrentCulture, Resources.UnfoldVsTemplateCommand_UnexpectedException, settings.TemplateUri, owner.InstanceName, ex.Message)); } }
public override void RunStarted(object automationObject, Dictionary<string, string> replacementsDictionary, WizardRunKind runKind, object[] customParams) { base.RunStarted(automationObject, replacementsDictionary, runKind, customParams); if (this.PatternManager == null) { NuPatternCompositionService.Instance.SatisfyImportsOnce(this); } Guard.NotNull(() => this.PatternManager, this.PatternManager); Guard.NotNull(() => this.UriService, this.UriService); var safeProductName = GetSafeTemplateName(replacementsDictionary); this.templateFile = (string)customParams[0]; this.templateUri = this.UriService.CreateUri(this.TemplateSchema); if (!UnfoldScope.IsActive || !UnfoldScope.Current.HasUnfolded(templateUri.AbsoluteUri)) { var toolkit = FindToolkitOrThrow(this.PatternManager, templateFile); var settings = FindTemplateSettingsOrThrow(toolkit, templateUri); using (tracer.StartActivity(Resources.InstantiationTemplateWizard_StartingTemplateOriginated, this.TemplateSchema.PhysicalPath)) { if (settings.CreateElementOnUnfold) { if (!this.Solution.IsOpen && !this.PatternManager.IsOpen) { this.tempStoreFile = Path.GetTempFileName(); this.PatternManager.Open(this.tempStoreFile, true); } // We always create the new scope. If there's a wrapping EventBufferingTemplateWizard, we'll just // hook on top of that. Events that we buffer will not be raised until the outer buffering completes. eventBufferingScope = new StoreEventBufferingScope(); this.element = this.PatternManager.CreateProduct(toolkit, safeProductName); var templateAutomation = FindTemplateAutomationOrThrow(this.element, this.templateUri.AbsoluteUri); if (settings.SyncName && settings.TargetFileName.ValueProvider != null) throw new NotSupportedException(Resources.TemplateAutomation_ValueProviderUnsupportedForSyncNames); this.templateScope = new UnfoldScope( templateAutomation, new ReferenceTag { SyncNames = settings.SyncName, TargetFileName = settings.TargetFileName.Value }, this.templateUri.AbsoluteUri); if (!templateAutomation.ExecuteWizard()) { if (this.templateScope != null) { this.PatternManager.Close(); File.Delete(this.tempStoreFile); throw new WizardCancelledException(); } else { wizardCancelled = true; } } } } } }