void IActionExecutionService.Execute(string actionName, Dictionary <string, object> inputValues) { IDictionaryService combinedValues = new SuplementedDictionaryService(inputValues, GetService <IDictionaryService>(true)); currentAction = actionName; IAction action = actionInstances[actionName]; Config.Action actionConfig = Configuration.Actions[actionName]; SetupInputs(action, actionConfig, actionInstances, combinedValues); ValidateOutput(action, actionConfig); // Site the action if it's a component. if (action is IComponent) { Add((IComponent)action, actionName); } // Pass values if IAttributesConfigurable is implemented, // and do final pass on required input properties. FinalizeSetup(action, actionConfig); action.Execute(); executedActions.Add(action); executedNameActions.Add(actionName); }
private void FinalizeSetup(IAction action, Configuration.Action config) { if (action is IAttributesConfigurable) { Configure((IAttributesConfigurable)action, config.AnyAttr); } using (new UnsiteComponent(action)) { PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(action); // Check all required input arguments prior to execution. // Some may not be included in the configuration file and // may thus not be checked above. foreach (PropertyDescriptor property in properties) { InputAttribute actioninput = (InputAttribute)property.Attributes[typeof(InputAttribute)]; if (actioninput != null && actioninput.Required) { object propertyvalue = property.GetValue(action); if (propertyvalue == null || (propertyvalue is String && ((String)propertyvalue).Length == 0)) { throw new ArgumentNullException(property.Name, Properties.Resources.General_ArgumentEmpty); } } } } }
private void ValidateOutput(IAction action, Configuration.Action config) { if (config.Output != null) { foreach (Config.Output parameter in config.Output) { // Retrieve the property using the type description also for extensibility. PropertyDescriptor outprop; using (new UnsiteComponent(action)) { outprop = TypeDescriptor.GetProperties(action).Find(parameter.Name, false); if (outprop != null && (outprop.Attributes[typeof(OutputAttribute)] == null)) { throw new NotSupportedException(String.Format( System.Globalization.CultureInfo.CurrentCulture, Properties.Resources.Recipe_ActionOutputInvalid, parameter.Name, config.Name, action.GetType())); } } if (outprop == null) { throw new ActionExecutionException( this.Configuration.Name, config.Name, String.Format(System.Globalization.CultureInfo.CurrentCulture, Properties.Resources.Recipe_ActionPropertyMissing, parameter.Name, action.GetType())); } } } }
private object GetActionOutputValue(Configuration.Action config, Configuration.Input parameter, object value) { string[] actionoutvalues = parameter.ActionOutput.Split(new char[] { '.' }); object outaction = actionInstances[actionoutvalues[0]]; if (outaction == null) { throw new ArgumentException(String.Format( System.Globalization.CultureInfo.CurrentCulture, Properties.Resources.Recipe_ActionOutputNull, config.Name, parameter.Name, actionoutvalues[0])); } // Use the type descriptor for the object, so it can be extensible. PropertyDescriptor outprop = GetComponentProperty(outaction, actionoutvalues[1]); bool HasOutputAttribute = false; if (outprop != null) { HasOutputAttribute = (outprop.Attributes[typeof(OutputAttribute)] != null); } if (!HasOutputAttribute) { throw new NotSupportedException(String.Format( System.Globalization.CultureInfo.CurrentCulture, Properties.Resources.Recipe_ActionOutputMissing, actionoutvalues[1], actionoutvalues[0], config.Name, outaction.GetType())); } return(outprop.GetValue(outaction)); }
private void SetupInputs(IAction action, Configuration.Action config, IDictionary actions, IDictionaryService arguments) { if (config.Input != null) { // Set input properties. foreach (Configuration.Input parameter in config.Input) { object value = null; if (parameter.RecipeArgument != null) { value = arguments.GetValue(parameter.RecipeArgument); } else if (parameter.ActionOutput != null) { value = GetActionOutputValue(config, parameter, value); } // Retrieve the property using the type description also for extensibility. PropertyDescriptor inprop = GetComponentProperty(action, parameter.Name); if (inprop != null) { InputAttribute inputattr = (InputAttribute)inprop.Attributes[typeof(InputAttribute)]; if (inputattr == null) { throw new NotSupportedException(String.Format( System.Globalization.CultureInfo.CurrentCulture, Properties.Resources.Recipe_NotMarkedInput, parameter.Name, config.Type)); } if (inputattr.Required && (value == null || (value is String && ((String)value).Length == 0))) { throw new ArgumentNullException(parameter.Name, Properties.Resources.General_ArgumentEmpty); } try { inprop.SetValue(action, value); } catch (TargetInvocationException tex) { // Throw with inner exception which contains the real error. throw new NotSupportedException(String.Format( System.Globalization.CultureInfo.CurrentCulture, Properties.Resources.Recipe_CantSetActionProperty, inprop.Name, config.Name), tex.InnerException); } } else { throw new ActionExecutionException( this.Configuration.Name, config.Name, String.Format(System.Globalization.CultureInfo.CurrentCulture, Properties.Resources.Recipe_ActionPropertyMissing, parameter.Name, action.GetType())); } } } }
public void SetUp() { recipeConfiguration = new Microsoft.Practices.RecipeFramework.Configuration.Recipe(); recipeConfiguration.Name = "Test"; Configuration.Action first = new Configuration.Action(); first.Name = "First"; first.Type = typeof(FirstAction).FullName; Configuration.Action second = new Configuration.Action(); second.Name = "Second"; second.Type = typeof(SecondAction).FullName; recipeConfiguration.Actions = new Configuration.RecipeActions(); recipeConfiguration.Actions.Action = new Configuration.Action[] { first, second }; container = new Microsoft.Practices.ComponentModel.ServiceContainer(); container.AddService(typeof(System.ComponentModel.Design.ITypeResolutionService), new MockResolutionService()); container.AddService(typeof(System.ComponentModel.Design.IDictionaryService), new MockDictionary()); container.AddService(typeof(Microsoft.Practices.RecipeFramework.Services.IConfigurationService), new MockConfigrationService()); container.AddService(typeof(IComponentChangeService), new MockChangeService()); container.AddService(typeof(IValueInfoService), new MockValueInfoService()); }
private Hashtable CreateFixupPages(int maxfields, XmlDocument xmlfactory, ArrayList arguments, ArrayList actions, ref Page lastpage, ArrayList pages, ref ArrayList fields, int nPages) { int iPage = 1; int iArgument = 1; bool firstPage = true; Hashtable referenceDictionary = new Hashtable(); foreach (FixupReference fixup in referencesToFix) { if (firstPage || (lastpage != null) && (fields.Count == maxfields)) { #region Create new page firstPage = false; // If we have fields and a previous page, set all fields in one shot. if (lastpage != null && fields != null) { lastpage.Fields = new Field[fields.Count]; fields.CopyTo(lastpage.Fields, 0); } // Start a new page for the fields. lastpage = new Page(); pages.Add(lastpage); fields = new ArrayList(maxfields); lastpage.Title = String.Format( CultureInfo.CurrentCulture, Properties.Resources.ReferenceRestoreService_PageTitle, iPage, nPages); lastpage.Help = String.Format( CultureInfo.CurrentCulture, Properties.Resources.ReferenceRestoreService_PageHelp); lastpage.LinkTitle = String.Format( CultureInfo.CurrentCulture, Properties.Resources.ReferenceRestoreService_PageLinkTitle, iPage, nPages); iPage++; #endregion Create new page } #region Setup recipe arguments Config.Argument argument = new Config.Argument(); argument.Name = string.Format(CultureInfo.InvariantCulture, "Argument{0}", iArgument); argument.Type = GetTargetType(fixup.ExpectedTargetKind).AssemblyQualifiedName; argument.Converter = new Config.Converter(); argument.Converter.Type = GetConverterType(fixup.ExpectedTargetKind); arguments.Add(argument); Config.Argument argumentKeyRef = new Config.Argument(); argumentKeyRef.Name = string.Format(CultureInfo.InvariantCulture, "Reference{0}", iArgument); argumentKeyRef.Type = "Microsoft.Practices.RecipeFramework.IAssetReference, Microsoft.Practices.RecipeFramework.Common"; referenceDictionary.Add(argumentKeyRef.Name, fixup.OldReference); arguments.Add(argumentKeyRef); iArgument++; #endregion Setup recipe arguments #region Create new field Field field = new Field(); if (fixup.OldReference is BoundTemplateReference) { int templateLength = fixup.OwningPackage.BasePath.Length + 11; //11 corresponds to Lenght of string "\Template\" if (templateLength > fixup.ReferencedAsset.Length) { templateLength = 0; } field.Label = string.Format("{0} ({1})", fixup.ReferencedAsset.Substring(templateLength), fixup.SavedTarget); field.Help = String.Format( CultureInfo.CurrentCulture, Properties.Resources.ReferenceRestoreService_FieldTemplateHelp, fixup.ExpectedTargetKind, fixup.ReferencedAsset.Substring(templateLength)); } else // case of recipe reference { IConfigurationService configService = (IConfigurationService)fixup.OwningPackage.GetService(typeof(IConfigurationService), true); Config.Recipe recipeReference = configService.CurrentPackage[fixup.OldReference.AssetName]; field.Label = string.Format("{0} ({1})", recipeReference.Caption, fixup.SavedTarget); field.Help = String.Format( CultureInfo.CurrentCulture, Properties.Resources.ReferenceRestoreService_FieldRecipeHelp, fixup.ExpectedTargetKind, recipeReference.Caption); } field.Tooltip = String.Format( CultureInfo.CurrentCulture, Properties.Resources.ReferenceRestoreService_FieldTooltip, fixup.SavedTarget, fixup.ExpectedTargetKind); field.InvalidValueMessage = String.Format( CultureInfo.CurrentCulture, Properties.Resources.ReferenceRestoreService_FieldInvalid, fixup.ExpectedTargetKind); field.ValueName = argument.Name; field.Editor = new Editor(); // Again, we can't use the type directly to avoid circular references. field.Editor.Type = "Microsoft.Practices.RecipeFramework.Library.Editors.SolutionPickerEditor, Microsoft.Practices.RecipeFramework.Library"; field.PanelType = "Microsoft.Practices.RecipeFramework.VisualStudio.Services.CustomArgumentPanel, Microsoft.Practices.RecipeFramework.VisualStudio"; fields.Add(field); #endregion Create new field #region Setup an action for it Config.Action action = new Config.Action(); // Name will be ugly, but we need to ensure uniqueness too. action.Name = argument.Name; action.Type = typeof(AddFixedReferenceAction).AssemblyQualifiedName; XmlAttribute assetattr; assetattr = xmlfactory.CreateAttribute("Recipe"); assetattr.Value = fixup.ReferencedAsset; XmlAttribute packageattr = xmlfactory.CreateAttribute("TargetPackage"); packageattr.Value = fixup.OwningPackage.Configuration.Name; action.AnyAttr = new XmlAttribute[] { assetattr, packageattr }; // Sync action input with collected argument for the target. Config.Input input = new Config.Input(); input.Name = "Target"; input.RecipeArgument = argument.Name; Config.Input inputRef = new Config.Input(); inputRef.Name = "OldReference"; inputRef.RecipeArgument = argumentKeyRef.Name; action.Input = new Config.Input[] { input, inputRef }; actions.Add(action); #endregion Setup an action for it } return(referenceDictionary); }