1 // Copyright (c) Microsoft Corporation. All rights reserved.
3 // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
4 // WHETHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
5 // WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
6 // THE ENTIRE RISK OF USE OR RESULTS IN CONNECTION WITH THE USE OF THIS CODE
7 // AND INFORMATION REMAINS WITH THE USER.
10 /*********************************************************************
11 * NOTE: A copy of this file exists at: WF\Common\Shared
12 * The two files must be kept in sync. Any change made here must also
13 * be made to WF\Common\Shared\CompModHelpers.cs
14 *********************************************************************/
16 namespace System.Workflow.Activities.Common
20 using System.Collections;
21 using System.Collections.Generic;
22 using System.ComponentModel;
23 using System.Diagnostics;
24 using System.ComponentModel.Design;
25 using System.ComponentModel.Design.Serialization;
26 using System.Workflow.ComponentModel.Serialization;
28 using System.Runtime.Serialization.Formatters.Binary;
29 using System.Windows.Forms;
31 using System.Drawing.Design;
32 using System.Workflow.ComponentModel;
33 using System.Workflow.ComponentModel.Compiler;
35 using System.Reflection;
37 using System.Globalization;
38 using Microsoft.Win32;
39 using System.Runtime.InteropServices;
40 using System.Diagnostics.CodeAnalysis;
41 using System.Workflow.ComponentModel.Design;
44 internal static class Helpers
46 private static readonly string VSExtensionProductRegistrySubKey = "Visual Studio Ext for Windows Workflow";
49 internal static readonly string ProductRootRegKey = @"SOFTWARE\Microsoft\Net Framework Setup\NDP\v4.0\Setup\Windows Workflow Foundation";
50 internal static readonly string ProductInstallDirectory = GetInstallDirectory(false);
51 internal static readonly string ProductSDKInstallDirectory = GetInstallDirectory(true);
52 internal static readonly string TypeProviderAssemblyRegValueName = "References";
54 private static readonly string ProductRootRegKey30 = @"SOFTWARE\Microsoft\Net Framework Setup\NDP\v3.0\Setup\Windows Workflow Foundation";
55 internal static readonly string ProductInstallDirectory30 = GetInstallDirectory30();
57 private const string ProductCode = "{B644FB52-BB3D-4C43-80EC-57644210536A}";
58 private const string ProductSDKCode = "{C8A7718A-FF6D-4DDC-AE36-BBF968D6799B}";
59 private const string INSTALLPROPERTY_INSTALLLOCATION = "InstallLocation";
61 internal const int FILENAME_MAX = 260; //"stdio.h"
63 [SuppressMessage("Microsoft.Globalization", "CA1307:SpecifyStringComparison", Justification = "LastIndexOf(\"\\\") not a security issue.")]
64 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
65 internal static string PerUserRegistryKey
69 string keyPath = String.Empty;
70 using (RegistryKey userRegistryKey = Application.UserAppDataRegistry)
72 keyPath = userRegistryKey.ToString().Substring(Registry.CurrentUser.ToString().Length + 1);
73 keyPath = keyPath.Substring(0, keyPath.LastIndexOf("\\"));
74 keyPath += "\\" + VSExtensionProductRegistrySubKey;
80 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
81 private static string TypeProviderRegistryKeyPath
85 return PerUserRegistryKey + "\\TypeProvider";
89 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
90 internal static bool IsFileNameValid(string fileName)
92 int length = Path.GetInvalidPathChars().GetLength(0) + 5;
93 char[] invalidChars = new char[length];
94 Path.GetInvalidPathChars().CopyTo(invalidChars, 0);
95 invalidChars[length - 5] = ':';
96 invalidChars[length - 4] = '?';
97 invalidChars[length - 3] = '*';
98 invalidChars[length - 2] = '/';
99 invalidChars[length - 1] = '\\';
101 return (fileName != null &&
102 fileName.Length != 0 &&
103 fileName.Length <= FILENAME_MAX &&
104 fileName.IndexOfAny(invalidChars) == -1);
107 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
108 internal static bool AreAllActivities(ICollection c)
111 throw new ArgumentNullException("c");
113 foreach (object obj in c)
115 if (!(obj is Activity))
121 // this will return IDictionary, whose keys are parent and value is arraylist of child activities
122 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
123 internal static IDictionary PairUpCommonParentActivities(ICollection activities)
125 if (activities == null)
126 throw new ArgumentNullException("activities");
128 Hashtable commonParentActivities = new Hashtable();
129 foreach (Activity activity in activities)
131 if (activity.Parent != null)
133 ArrayList childActivities = (ArrayList)commonParentActivities[activity.Parent];
134 if (childActivities == null)
136 childActivities = new ArrayList();
137 commonParentActivities.Add(activity.Parent, childActivities);
139 childActivities.Add(activity);
142 return commonParentActivities;
145 // this will remove any activity from the collection whose parent is already there in the collection
146 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
147 internal static Activity[] GetTopLevelActivities(ICollection activities)
149 if (activities == null)
150 throw new ArgumentNullException("activities");
152 List<Activity> filteredActivities = new List<Activity>();
153 foreach (object obj in activities)
155 Activity activity = obj as Activity;
156 if (activity != null)
158 bool foundParent = false;
159 Activity parentActivity = activity.Parent;
160 while (parentActivity != null && !foundParent)
162 foreach (object obj2 in activities)
164 if (obj2 == parentActivity)
170 parentActivity = parentActivity.Parent;
174 filteredActivities.Add(activity);
177 return filteredActivities.ToArray();
180 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
181 internal static Activity[] GetNestedActivities(CompositeActivity compositeActivity)
184 if (compositeActivity == null)
185 throw new ArgumentNullException("compositeActivity");
187 IList<Activity> childActivities = null;
188 ArrayList nestedActivities = new ArrayList();
189 Queue compositeActivities = new Queue();
190 compositeActivities.Enqueue(compositeActivity);
191 while (compositeActivities.Count > 0)
193 CompositeActivity compositeActivity2 = (CompositeActivity)compositeActivities.Dequeue();
194 childActivities = compositeActivity2.Activities;
196 foreach (Activity activity in childActivities)
198 nestedActivities.Add(activity);
199 if (activity is CompositeActivity)
200 compositeActivities.Enqueue(activity);
203 return (Activity[])nestedActivities.ToArray(typeof(Activity));
207 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
208 internal static IList GetIdentifiersInCompositeActivity(CompositeActivity compositeActivity)
210 ArrayList identifiers = new ArrayList();
211 if (compositeActivity != null)
213 identifiers.Add(compositeActivity.Name);
214 IList<Activity> allChildren = GetAllNestedActivities(compositeActivity);
215 foreach (Activity activity in allChildren)
216 identifiers.Add(activity.Name);
218 return ArrayList.ReadOnly(identifiers);
221 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
222 internal static Activity[] GetAllNestedActivities(CompositeActivity compositeActivity)
224 if (compositeActivity == null)
225 throw new ArgumentNullException("compositeActivity");
227 ArrayList nestedActivities = new ArrayList();
229 // Note: GetAllNestedActivities will not check for black box activities.
230 // This is to allow it to be invoked from within the activity's
232 //if(Helpers.IsCustomActivity(compositeActivity))
233 //return (Activity[])nestedActivities.ToArray(typeof(Activity));
235 Queue compositeActivities = new Queue();
236 compositeActivities.Enqueue(compositeActivity);
237 while (compositeActivities.Count > 0)
239 CompositeActivity compositeActivity2 = (CompositeActivity)compositeActivities.Dequeue();
240 if (compositeActivity2 == compositeActivity || !Helpers.IsCustomActivity(compositeActivity2))
242 foreach (Activity activity in compositeActivity2.Activities)
244 nestedActivities.Add(activity);
245 if (activity is CompositeActivity)
246 compositeActivities.Enqueue(activity);
249 foreach (Activity activity in compositeActivity2.EnabledActivities)
251 if (!nestedActivities.Contains(activity))
253 nestedActivities.Add(activity);
254 if (activity is CompositeActivity)
255 compositeActivities.Enqueue(activity);
260 return (Activity[])nestedActivities.ToArray(typeof(Activity));
263 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
264 internal static string MergeNamespaces(string primaryNs, string secondaryNs)
266 string newNs = primaryNs;
267 if (secondaryNs != null && secondaryNs.Length > 0)
269 if (newNs != null && newNs.Length > 0)
270 newNs += ("." + secondaryNs);
276 newNs = string.Empty;
280 internal static Activity GetRootActivity(Activity activity)
282 if (activity == null)
283 throw new ArgumentNullException("activity");
285 while (activity.Parent != null)
286 activity = activity.Parent;
291 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
292 internal static Stream SerializeDesignersToStream(ICollection activities)
294 Stream stateStream = new MemoryStream();
295 BinaryWriter writer = new BinaryWriter(stateStream);
297 Queue<IComponent> serializedComponents = new Queue<IComponent>();
298 foreach (IComponent activity in activities)
299 serializedComponents.Enqueue(activity);
301 while (serializedComponents.Count > 0)
303 IComponent component = serializedComponents.Dequeue();
304 if (component != null && component.Site != null)
306 IDesignerHost designerHost = component.Site.GetService(typeof(IDesignerHost)) as IDesignerHost;
307 if (designerHost == null)
308 throw new InvalidOperationException(
309 SR.GetString(SR.General_MissingService, typeof(IDesignerHost).Name));
311 ActivityDesigner activityDesigner = designerHost.GetDesigner(component) as ActivityDesigner;
312 if (activityDesigner != null)
316 ((IPersistUIState)activityDesigner).SaveViewState(writer);
318 CompositeActivity compositeActivity = component as CompositeActivity;
319 if (compositeActivity != null)
321 foreach (IComponent childActivity in compositeActivity.Activities)
323 serializedComponents.Enqueue(childActivity);
337 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
338 internal static void DeserializeDesignersFromStream(ICollection activities, Stream stateStream)
340 if (stateStream.Length == 0)
343 BinaryReader reader = new BinaryReader(stateStream);
344 stateStream.Seek(0, SeekOrigin.Begin);
346 Queue<IComponent> serializedComponents = new Queue<IComponent>();
347 foreach (IComponent component in activities)
348 serializedComponents.Enqueue(component);
350 while (serializedComponents.Count > 0)
352 IComponent component = serializedComponents.Dequeue();
353 if (component != null && component.Site != null)
355 IDesignerHost designerHost = component.Site.GetService(typeof(IDesignerHost)) as IDesignerHost;
356 if (designerHost == null)
357 throw new InvalidOperationException(
358 SR.GetString(SR.General_MissingService, typeof(IDesignerHost).Name));
360 ActivityDesigner activityDesigner = designerHost.GetDesigner(component) as ActivityDesigner;
361 if (activityDesigner != null)
365 ((IPersistUIState)activityDesigner).LoadViewState(reader);
367 CompositeActivity compositeActivity = component as CompositeActivity;
368 if (compositeActivity != null)
370 foreach (IComponent childActivity in compositeActivity.Activities)
372 serializedComponents.Enqueue(childActivity);
384 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
385 internal static string GetBaseIdentifier(Activity activity)
387 string baseIdentifier = activity.GetType().Name;
388 StringBuilder b = new StringBuilder(baseIdentifier.Length);
389 for (int i = 0; i < baseIdentifier.Length; i++)
391 if (Char.IsUpper(baseIdentifier[i]) && (i == 0 || i == baseIdentifier.Length - 1 || Char.IsUpper(baseIdentifier[i + 1])))
393 b.Append(Char.ToLowerInvariant(baseIdentifier[i]));
397 b.Append(baseIdentifier.Substring(i));
404 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
405 internal static string GetRootNamespace(IServiceProvider serviceProvider)
407 if (serviceProvider == null)
408 throw new ArgumentNullException("serviceProvider");
410 string rootNs = string.Empty;
411 IWorkflowCompilerOptionsService compilerOptionsService = (IWorkflowCompilerOptionsService)serviceProvider.GetService(typeof(IWorkflowCompilerOptionsService));
412 if (compilerOptionsService != null && compilerOptionsService.RootNamespace != null)
413 rootNs = compilerOptionsService.RootNamespace; //e.g. WorkflowApp1
417 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
418 internal static Type GetDataSourceClass(Activity activity, IServiceProvider serviceProvider)
420 if (activity == null)
421 throw new ArgumentNullException("activity");
422 if (serviceProvider == null)
423 throw new ArgumentNullException("serviceProvider");
425 Type activityType = null;
426 string className = null;
427 if (activity == GetRootActivity(activity))
428 className = activity.GetValue(WorkflowMarkupSerializer.XClassProperty) as String;
430 if (!String.IsNullOrEmpty(className))
432 ITypeProvider typeProvider = (ITypeProvider)serviceProvider.GetService(typeof(ITypeProvider));
433 if (typeProvider == null)
434 throw new InvalidOperationException(
435 SR.GetString(SR.General_MissingService, typeof(ITypeProvider).Name));
437 activityType = typeProvider.GetType(className);
441 return activity.GetType();
447 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
448 internal static Activity GetDataSourceActivity(Activity activity, string inputName, out string name)
450 if (activity == null)
451 throw new ArgumentNullException("activity");
452 if (string.IsNullOrEmpty(inputName))
453 throw new ArgumentException("inputName");
456 if (inputName.IndexOf('.') == -1)
459 int indexOfDot = inputName.LastIndexOf('.');
460 string scopeID = inputName.Substring(0, indexOfDot);
461 name = inputName.Substring(indexOfDot + 1);
463 Activity contextActivity = Helpers.ParseActivityForBind(activity, scopeID);
464 if (contextActivity == null)
465 contextActivity = Helpers.ParseActivity(Helpers.GetRootActivity(activity), scopeID);
467 // activity can be either the qualified id of the scope activity or the qualified id of the custom activity.
468 return contextActivity;
471 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
472 internal static void GetNamespaceAndClassName(string fullQualifiedName, out string namespaceName, out string className)
474 namespaceName = String.Empty;
475 className = String.Empty;
477 if (fullQualifiedName == null)
480 int indexOfDot = fullQualifiedName.LastIndexOf('.');
481 if (indexOfDot != -1)
483 namespaceName = fullQualifiedName.Substring(0, indexOfDot);
484 className = fullQualifiedName.Substring(indexOfDot + 1);
488 className = fullQualifiedName;
492 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
493 internal static CodeTypeDeclaration GetCodeNamespaceAndClass(CodeNamespaceCollection namespaces, string namespaceName, string className, out CodeNamespace codeNamespace)
495 codeNamespace = null;
496 foreach (CodeNamespace ns in namespaces)
498 if (ns.Name == namespaceName)
505 CodeTypeDeclaration codeTypeDeclaration = null;
506 if (codeNamespace != null)
508 foreach (CodeTypeDeclaration typeDecl in codeNamespace.Types)
510 if (typeDecl.Name == className)
512 codeTypeDeclaration = typeDecl;
517 return codeTypeDeclaration;
520 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
521 internal static string GetClassName(string fullQualifiedName)
523 if (fullQualifiedName == null)
526 string className = fullQualifiedName;
527 int indexOfDot = fullQualifiedName.LastIndexOf('.');
528 if (indexOfDot != -1)
529 className = fullQualifiedName.Substring(indexOfDot + 1);
534 [DllImport("msi.dll", SetLastError = true, ExactSpelling = true, CharSet = CharSet.Auto)]
535 private static extern int MsiGetProductInfoW(string szProduct, string szProperty, StringBuilder lpValueBuf, ref int pcchValueBuf);
536 private static string GetInstallDirectory(bool getSDKDir)
538 string path = string.Empty;
541 //ERROR_UNKNOWN_PROPERTY 1608L
542 //ERROR_INVALID_PARAMETER 87L
543 int length = FILENAME_MAX + 1;
544 StringBuilder location = new StringBuilder(length);
545 int hr = MsiGetProductInfoW(getSDKDir ? ProductSDKCode : ProductCode, INSTALLPROPERTY_INSTALLLOCATION, location, ref length);
546 int error = Marshal.GetLastWin32Error();
549 path = location.ToString();
553 Debug.WriteLine("Error loading install directory: " + error.ToString(CultureInfo.CurrentCulture));
561 if (string.IsNullOrEmpty(path))
567 using (RegistryKey key = Registry.LocalMachine.OpenSubKey(ProductRootRegKey))
570 path = (string)key.GetValue("InstallDir");
580 if (string.IsNullOrEmpty(path))
581 path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
586 private static string GetInstallDirectory30()
588 string path = string.Empty;
591 //ERROR_UNKNOWN_PROPERTY 1608L
592 //ERROR_INVALID_PARAMETER 87L
593 int length = FILENAME_MAX + 1;
594 StringBuilder location = new StringBuilder(length);
595 int hr = MsiGetProductInfoW(ProductCode, INSTALLPROPERTY_INSTALLLOCATION, location, ref length);
596 int error = Marshal.GetLastWin32Error();
599 path = location.ToString();
603 Debug.WriteLine("Error loading 3.0 install directory: " + error.ToString(CultureInfo.CurrentCulture));
611 if (string.IsNullOrEmpty(path))
615 using (RegistryKey key = Registry.LocalMachine.OpenSubKey(ProductRootRegKey30))
619 path = (string)key.GetValue("InstallDir");
631 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
632 internal static Type GetBaseType(PropertyInfo property, object owner, IServiceProvider serviceProvider)
634 //When we are emitting code for the dynamic properties we might get the propertyinfo as null
636 throw new ArgumentNullException("owner");
638 if (serviceProvider == null)
639 throw new ArgumentNullException("serviceProvider");
641 if (property != null)
643 IDynamicPropertyTypeProvider basetypeProvider = owner as IDynamicPropertyTypeProvider;
644 if (basetypeProvider != null)
646 Type type = basetypeProvider.GetPropertyType(serviceProvider, property.Name);
651 return property.PropertyType;
658 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
659 internal static AccessTypes GetAccessType(PropertyInfo property, object owner, IServiceProvider serviceProvider)
661 //When we are emitting code for the dynamic properties we might get the propertyinfo as null
663 throw new ArgumentNullException("owner");
665 if (serviceProvider == null)
666 throw new ArgumentNullException("serviceProvider");
668 if (property != null)
670 IDynamicPropertyTypeProvider basetypeProvider = owner as IDynamicPropertyTypeProvider;
671 if (basetypeProvider != null)
672 return basetypeProvider.GetAccessType(serviceProvider, property.Name);
675 return AccessTypes.Read;
678 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
679 internal static bool IsChildActivity(CompositeActivity parent, Activity activity)
681 foreach (Activity containedActivity in parent.Activities)
683 if (activity == containedActivity)
686 if (containedActivity is CompositeActivity &&
687 Helpers.IsChildActivity(containedActivity as CompositeActivity, activity))
694 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
695 internal static bool TypesEqual(CodeTypeReference typeLeft, Type typeRight)
697 if (typeRight.IsArray && typeLeft.ArrayRank != typeRight.GetArrayRank()) return false;
699 if (!typeLeft.BaseType.Equals(typeRight.FullName)) return false;
701 if (typeLeft.ArrayRank > 0)
702 return TypesEqual(typeLeft.ArrayElementType, typeRight.GetElementType());
706 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
707 internal static bool TypesEqual(CodeTypeReference typeLeft, CodeTypeReference typeRight)
709 if (typeLeft.ArrayRank != typeRight.ArrayRank) return false;
710 if (!typeLeft.BaseType.Equals(typeRight.BaseType)) return false;
712 if (typeLeft.ArrayRank > 0)
713 return TypesEqual(typeLeft.ArrayElementType, typeRight.ArrayElementType);
717 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
718 internal static DesignerSerializationVisibility GetSerializationVisibility(MemberInfo memberInfo)
721 if (memberInfo == null)
722 throw new ArgumentNullException("memberInfo");
724 DesignerSerializationVisibility designerSerializationVisibility = DesignerSerializationVisibility.Visible;
726 // Calling GetCustomAttributes on PropertyInfo or EventInfo when the inherit parameter of GetCustomAttributes
727 // is true does not walk the type hierarchy. But System.Attribute.GetCustomAttributes causes perf issues.
728 object[] attributes = memberInfo.GetCustomAttributes(typeof(DesignerSerializationVisibilityAttribute), true);
729 if (attributes.Length > 0)
730 designerSerializationVisibility = (attributes[0] as DesignerSerializationVisibilityAttribute).Visibility;
731 else if (Attribute.IsDefined(memberInfo, typeof(DesignerSerializationVisibilityAttribute)))
732 designerSerializationVisibility = (Attribute.GetCustomAttribute(memberInfo, typeof(DesignerSerializationVisibilityAttribute)) as DesignerSerializationVisibilityAttribute).Visibility;
734 return designerSerializationVisibility;
737 // Method parameters must match exactly
739 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
740 internal static MethodInfo GetMethodExactMatch(Type type, string name, BindingFlags bindingAttr, Binder binder, Type[] types, ParameterModifier[] modifiers)
742 MethodInfo foundMethod = null;
743 MethodInfo[] methods = type.GetMethods(bindingAttr);
744 foreach (MethodInfo method in methods)
746 bool matchName = ((bindingAttr & BindingFlags.IgnoreCase) == BindingFlags.IgnoreCase) ? string.Compare(method.Name, name, StringComparison.OrdinalIgnoreCase) == 0 : string.Compare(method.Name, name, StringComparison.Ordinal) == 0;
749 bool mismatch = false;
752 ParameterInfo[] parameters = method.GetParameters();
753 if (parameters.GetLength(0) == types.Length)
755 for (int index = 0; !mismatch && index < parameters.Length; index++)
756 mismatch = (parameters[index].ParameterType == null) || (!parameters[index].ParameterType.IsAssignableFrom(types[index]));
763 foundMethod = method;
772 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
773 internal static T GetAttributeFromObject<T>(object attributeObject) where T : Attribute
775 if (attributeObject is AttributeInfoAttribute)
776 return (T)((AttributeInfoAttribute)attributeObject).AttributeInfo.CreateAttribute();
778 if (attributeObject is T)
779 return (T)attributeObject;
784 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
785 internal static Type GetDelegateFromEvent(EventInfo eventInfo)
787 if (eventInfo.EventHandlerType != null)
788 return eventInfo.EventHandlerType;
790 return TypeProvider.GetEventHandlerType(eventInfo);
793 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
794 internal static void AddTypeProviderAssembliesFromRegistry(TypeProvider typeProvider, IServiceProvider serviceProvider)
796 if (typeProvider == null)
797 throw new ArgumentNullException("typeProvider");
798 if (serviceProvider == null)
799 throw new ArgumentNullException("serviceProvider");
801 RegistryKey referenceKey = Registry.CurrentUser.OpenSubKey(TypeProviderRegistryKeyPath);
802 if (referenceKey != null)
804 ITypeProviderCreator typeProviderCreator = serviceProvider.GetService(typeof(ITypeProviderCreator)) as ITypeProviderCreator;
805 foreach (string assemblyName in ((string[])referenceKey.GetValue(TypeProviderAssemblyRegValueName)))
809 if (typeProviderCreator != null)
811 bool addAssembly = true;
812 Assembly assembly = typeProviderCreator.GetTransientAssembly(AssemblyName.GetAssemblyName(assemblyName));
813 // Check to see if a copy of the assembly is already added.
814 if (assembly != null)
816 foreach (Type type in assembly.GetTypes())
818 if (typeProvider.GetType(type.AssemblyQualifiedName) != null)
823 typeProvider.AddAssembly(assembly);
827 // AddAssemblyReference should take care of duplicates.
828 typeProvider.AddAssemblyReference(assemblyName);
837 referenceKey.Close();
841 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
842 internal static void UpdateTypeProviderAssembliesRegistry(string assemblyName)
844 RegistryKey referenceKey = Registry.CurrentUser.CreateSubKey(TypeProviderRegistryKeyPath);
845 if (referenceKey != null)
849 ArrayList references = null;
850 if (referenceKey.ValueCount > 0)
851 references = new ArrayList((string[])referenceKey.GetValue(TypeProviderAssemblyRegValueName));
853 references = new ArrayList();
855 if (!references.Contains(assemblyName))
857 references.Add(assemblyName);
858 referenceKey.SetValue(TypeProviderAssemblyRegValueName, ((string[])references.ToArray(typeof(string))));
863 //We eat the exception
867 referenceKey.Close();
872 internal static CompositeActivity GetDeclaringActivity(Activity activity)
874 if (activity == null)
875 throw new ArgumentNullException("activity");
877 CompositeActivity parent = activity.Parent;
878 while (parent != null)
880 // This will be the root
881 if (parent.Parent == null)
884 // Any custom activity found is the declaring activity
885 if (IsCustomActivity(parent))
888 parent = parent.Parent;
893 internal static bool IsActivityLocked(Activity activity)
895 if (activity == null)
896 throw new ArgumentNullException("activity");
898 CompositeActivity parent = activity.Parent;
899 while (parent != null)
901 // If root, not locked
902 if (parent.Parent == null)
905 // Any custom activity found, then locked
906 if (IsCustomActivity(parent))
909 parent = parent.Parent;
915 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
916 internal static Activity GetEnclosingActivity(Activity activity)
918 Activity enclosingActivity;
920 if (IsActivityLocked(activity))
921 enclosingActivity = Helpers.GetDeclaringActivity(activity);
923 enclosingActivity = GetRootActivity(activity);
925 return enclosingActivity;
928 // This function returns all the executable activities including secondary flow activities.
929 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
930 public static IList<Activity> GetAllEnabledActivities(CompositeActivity compositeActivity)
932 if (compositeActivity == null)
933 throw new ArgumentNullException("compositeActivity");
935 List<Activity> allActivities = new List<Activity>(compositeActivity.EnabledActivities);
936 foreach (Activity childActivity in compositeActivity.Activities)
938 if (childActivity.Enabled &&
939 IsFrameworkActivity(childActivity))
940 allActivities.Add(childActivity);
942 return allActivities;
944 public static bool IsFrameworkActivity(Activity activity)
946 return (activity is CancellationHandlerActivity ||
947 activity is CompensationHandlerActivity ||
948 activity is FaultHandlersActivity);
951 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
952 internal static MethodInfo GetInterfaceMethod(Type interfaceType, string methodName)
954 MethodInfo methodInfo = null;
955 string interfaceName = String.Empty;
956 string method = String.Empty;
958 if (methodName.LastIndexOf('.') > 0)
960 interfaceName = methodName.Substring(0, methodName.LastIndexOf('.'));
961 method = methodName.Substring(methodName.LastIndexOf('.') + 1);
964 if (!String.IsNullOrEmpty(interfaceName))
966 foreach (Type inheritedInterface in interfaceType.GetInterfaces())
968 if (String.Compare(inheritedInterface.FullName, interfaceName, StringComparison.Ordinal) == 0)
970 methodInfo = inheritedInterface.GetMethod(method);
977 methodInfo = interfaceType.GetMethod(methodName);
983 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
984 internal static XmlWriter CreateXmlWriter(object output)
986 XmlWriterSettings settings = new XmlWriterSettings();
987 settings.Indent = true;
988 settings.IndentChars = ("\t");
989 settings.OmitXmlDeclaration = true;
990 settings.CloseOutput = true;
992 if (output is string)
993 return XmlWriter.Create(output as string, settings);
994 else if (output is TextWriter)
995 return XmlWriter.Create(output as TextWriter, settings);
998 Debug.Assert(false, "Invalid argument type. 'output' must either be string or TextWriter.");
1003 #region DesignTimeType Support
1004 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
1005 internal static string GetDesignTimeTypeName(object owner, object key)
1007 string typeName = null;
1008 DependencyObject dependencyObject = owner as DependencyObject;
1009 if (dependencyObject != null && key != null)
1011 if (dependencyObject.UserData.Contains(UserDataKeys.DesignTimeTypeNames))
1013 Hashtable typeNames = dependencyObject.UserData[UserDataKeys.DesignTimeTypeNames] as Hashtable;
1014 if (typeNames != null && typeNames.ContainsKey(key))
1015 typeName = typeNames[key] as string;
1021 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
1022 internal static void SetDesignTimeTypeName(object owner, object key, string value)
1024 DependencyObject dependencyObject = owner as DependencyObject;
1025 if (dependencyObject != null && key != null)
1027 if (!dependencyObject.UserData.Contains(UserDataKeys.DesignTimeTypeNames))
1028 dependencyObject.UserData[UserDataKeys.DesignTimeTypeNames] = new Hashtable();
1030 Hashtable typeNames = dependencyObject.UserData[UserDataKeys.DesignTimeTypeNames] as Hashtable;
1031 typeNames[key] = value;
1036 #region Helpers from ExecutableCompModHelpers
1037 // This only works for composite activity.
1038 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
1039 internal static bool IsCustomActivity(CompositeActivity compositeActivity)
1041 if (compositeActivity == null)
1042 throw new ArgumentNullException("compositeActivity");
1044 if (compositeActivity.UserData.Contains(UserDataKeys.CustomActivity))
1046 return (bool)(compositeActivity.UserData[UserDataKeys.CustomActivity]);
1052 CompositeActivity activity = Activator.CreateInstance(compositeActivity.GetType()) as CompositeActivity;
1053 if (activity != null && activity.Activities.Count > 0)
1055 compositeActivity.UserData[UserDataKeys.CustomActivityDefaultName] = activity.Name;
1056 compositeActivity.UserData[UserDataKeys.CustomActivity] = true; //
1066 compositeActivity.UserData[UserDataKeys.CustomActivity] = false; //
1070 [SuppressMessage("Microsoft.Globalization", "CA1307:SpecifyStringComparison", Justification = "IndexOf(\".\") not a security issue.")]
1071 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
1072 internal static Activity ParseActivity(Activity parsingContext, string activityName)
1074 if (parsingContext == null)
1075 throw new ArgumentNullException("parsingContext");
1076 if (activityName == null)
1077 throw new ArgumentNullException("activityName");
1079 string currentAtivityName = activityName;
1080 string nextActivityName = string.Empty;
1081 int indexOfDot = activityName.IndexOf(".");
1082 if (indexOfDot != -1)
1084 currentAtivityName = activityName.Substring(0, indexOfDot);
1085 nextActivityName = activityName.Substring(indexOfDot + 1);
1086 if (nextActivityName.Length == 0)
1090 Activity currentActivity = GetActivity(parsingContext, currentAtivityName);
1091 if (currentActivity != null)
1093 if (nextActivityName.Length > 0)
1095 if (!(currentActivity is CompositeActivity) || !IsCustomActivity(currentActivity as CompositeActivity))
1096 // current activity must be a custom activity, otherwise there should be no dots in the name.
1099 string[] names = nextActivityName.Split('.');
1100 for (int i = 0; i < names.Length; i++)
1102 Activity nextActivity = GetActivity(currentActivity, names[i]);
1103 if (nextActivity == null || !Helpers.IsActivityLocked(nextActivity))
1106 CompositeActivity declaringActivity = GetDeclaringActivity(nextActivity);
1107 if (currentActivity != declaringActivity)
1110 currentActivity = nextActivity;
1113 return currentActivity;
1117 // This activity should always be unlocked, unless if GetChildActivity() is called from
1118 // within the custom activity's companion class, then we don't have the full qualified ID available
1119 // at that time. We allow this to succeed only if the declaring activity is the same as the declaring
1120 // activity of the context activity passed in.
1121 if (Helpers.IsActivityLocked(currentActivity))//.IsLocked)
1123 if (!IsDeclaringActivityMatchesContext(currentActivity, parsingContext))
1127 return currentActivity;
1134 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
1135 internal static Activity ParseActivityForBind(Activity context, string activityName)
1137 if (context == null)
1138 throw new ArgumentNullException("context");
1139 if (activityName == null)
1140 throw new ArgumentNullException("activityName");
1142 if (string.Equals(activityName, "/Self", StringComparison.Ordinal))
1146 else if (activityName.StartsWith("/Parent", StringComparison.OrdinalIgnoreCase))
1148 Activity activity = context;
1149 string[] paths = activityName.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
1150 for (int i = 0; i < paths.Length && activity != null; i++)
1152 string parent = paths[i].Trim();
1153 activity = (string.Equals(parent, "Parent", StringComparison.OrdinalIgnoreCase)) ? activity.Parent : null;
1157 else if (Helpers.IsActivityLocked(context))
1159 // Look for the matching activity inside the custom activity context first. This is because if a bind
1160 // is coming from a custom activity, it's activity ref ID may not match the qualified ID of the
1162 Activity activity = null;
1163 Activity declaringActivity = Helpers.GetDeclaringActivity(context);
1164 Guid currentContextGuid = GetRuntimeContextGuid(context);
1165 Guid declaringContextGuid = GetRuntimeContextGuid(declaringActivity);
1167 Activity currentContextActivity = context;
1168 Activity parentContextActivity = context.Parent;
1169 Guid parentContextGuid = GetRuntimeContextGuid(parentContextActivity);
1170 while (activity == null && declaringContextGuid != currentContextGuid)
1176 while (parentContextActivity != null && parentContextGuid == currentContextGuid)
1178 currentContextActivity = parentContextActivity;
1179 parentContextActivity = parentContextActivity.Parent;
1180 parentContextGuid = GetRuntimeContextGuid(parentContextActivity);
1183 activity = Helpers.ParseActivity(currentContextActivity, activityName);
1184 currentContextGuid = parentContextGuid;
1187 if (activity == null)
1189 // Check the declaring activity
1190 activity = Helpers.ParseActivity(declaringActivity, activityName);
1193 // Nothing found, let's see if this is bind to the custom activity itself.
1194 if (activity == null)
1196 if (!declaringActivity.UserData.Contains(UserDataKeys.CustomActivityDefaultName))
1198 //we need to activate a new instance of the declaringActivity's type and check if its name equals to the one we are looking for
1199 Activity newCustomActivity = Activator.CreateInstance(declaringActivity.GetType()) as Activity;
1200 declaringActivity.UserData[UserDataKeys.CustomActivityDefaultName] = newCustomActivity.Name;
1203 if (((string)declaringActivity.UserData[UserDataKeys.CustomActivityDefaultName]) == activityName)
1204 activity = declaringActivity;
1207 // if this is a locked activity, its bind reference must be within its declaring activity. We should not try
1208 // to resolve it beyond that scope.
1212 Activity targetActivity = null;
1213 Activity parentActivity = context;
1215 //if it's a custom activity and it has parent, start looking for the target activity at the parent level
1216 //otherwise we'll get children of the custom activity
1217 bool mayLookInside = false; //we may look inside the custom activity if the target is not found outside
1218 CompositeActivity compositeParentActivity = parentActivity as CompositeActivity;
1219 if (compositeParentActivity != null && parentActivity.Parent != null && IsCustomActivity(compositeParentActivity))
1221 mayLookInside = true;
1222 parentActivity = parentActivity.Parent;
1225 while (targetActivity == null && parentActivity != null)
1227 targetActivity = parentActivity.GetActivityByName(activityName, true);
1228 parentActivity = parentActivity.Parent;
1231 if (mayLookInside && targetActivity == null)
1233 //if we have not found an appropriate activity at the parent level, try looking inside
1234 //we dont need to look outside (loop while parent is not null) - it has already been done above
1235 parentActivity = context;
1236 targetActivity = parentActivity.GetActivityByName(activityName, true);
1240 return (targetActivity == null) ? Helpers.ParseActivity(Helpers.GetRootActivity(context), activityName) : targetActivity;
1243 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
1244 private static Guid GetRuntimeContextGuid(Activity currentActivity)
1246 Activity contextActivity = currentActivity;
1247 Guid contextGuid = (Guid)contextActivity.GetValue(Activity.ActivityContextGuidProperty);
1248 while (contextGuid == Guid.Empty && contextActivity.Parent != null)
1250 contextActivity = contextActivity.Parent;
1251 contextGuid = (Guid)contextActivity.GetValue(Activity.ActivityContextGuidProperty);
1256 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
1257 private static bool IsDeclaringActivityMatchesContext(Activity currentActivity, Activity context)
1259 CompositeActivity declaringContext = context as CompositeActivity;
1261 CompositeActivity declaringActivityOfCurrent = Helpers.GetDeclaringActivity(currentActivity);
1263 // If the context activity is locked and it is a primitive activity
1264 // or NOT a custom activity then we need to find its enclosing
1266 if (Helpers.IsActivityLocked(context) &&
1267 (declaringContext == null || !Helpers.IsCustomActivity(declaringContext))
1269 declaringContext = Helpers.GetDeclaringActivity(context);
1271 if (declaringContext == declaringActivityOfCurrent)
1277 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
1278 internal static bool IsAlternateFlowActivity(Activity activity)
1280 if (activity == null)
1283 bool isAlternateFlowActivityAttribute = false;
1284 //dont want to use reflection to check for the alternate flow attribute
1285 //this is a fix for a perf issue - use of reflection in a ui loop
1286 if (!activity.UserData.Contains(typeof(AlternateFlowActivityAttribute)))
1288 isAlternateFlowActivityAttribute = activity.GetType().GetCustomAttributes(typeof(AlternateFlowActivityAttribute), true).Length != 0;
1289 activity.UserData[typeof(AlternateFlowActivityAttribute)] = isAlternateFlowActivityAttribute;
1293 isAlternateFlowActivityAttribute = (bool)activity.UserData[typeof(AlternateFlowActivityAttribute)];
1296 return isAlternateFlowActivityAttribute;
1299 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
1300 private static Activity GetActivity(Activity containerActivity, string id)
1302 if (containerActivity != null)
1304 Queue activities = new Queue();
1305 activities.Enqueue(containerActivity);
1306 while (activities.Count > 0)
1308 Activity activity = (Activity)activities.Dequeue();
1309 if (activity.Enabled)
1311 if (activity.Name == id)
1314 if (activity is CompositeActivity)
1316 foreach (Activity child in ((CompositeActivity)activity).Activities)
1317 activities.Enqueue(child);
1328 #region Class TypeDescriptorContext (SHARED WITH ACTIVITIES, ORCHESTRATIONDESIGNER)
1329 [SuppressMessage("Microsoft.Performance", "CA1812:AvoidUninstantiatedInternalClasses",
1330 Justification = "Not all assemblies that include this file instantiate the class.")]
1331 internal sealed class TypeDescriptorContext : ITypeDescriptorContext
1333 private IServiceProvider serviceProvider;
1334 private PropertyDescriptor propDesc;
1335 private object instance;
1337 public TypeDescriptorContext(IServiceProvider serviceProvider, PropertyDescriptor propDesc, object instance)
1339 this.serviceProvider = serviceProvider;
1340 this.propDesc = propDesc;
1341 this.instance = instance;
1344 public IContainer Container
1348 return (IContainer)this.serviceProvider.GetService(typeof(IContainer));
1351 public object Instance
1355 return this.instance;
1358 public PropertyDescriptor PropertyDescriptor
1362 return this.propDesc;
1365 public object GetService(Type serviceType)
1367 return this.serviceProvider.GetService(serviceType);
1370 public bool OnComponentChanging()
1372 IComponentChangeService componentChangeService = (IComponentChangeService)this.serviceProvider.GetService(typeof(IComponentChangeService));
1373 if (componentChangeService != null)
1377 componentChangeService.OnComponentChanging(this.instance, this.propDesc);
1379 catch (CheckoutException ce)
1381 if (ce == CheckoutException.Canceled)
1389 public void OnComponentChanged()
1391 IComponentChangeService componentChangeService = (IComponentChangeService)this.serviceProvider.GetService(typeof(IComponentChangeService));
1392 if (componentChangeService != null)
1393 componentChangeService.OnComponentChanged(this.instance, this.propDesc, null, null);
1398 // This class has been added as a fix for
1402 internal static class DebuggerHelpers
1404 [SuppressMessage("Microsoft.Globalization", "CA1307:SpecifyStringComparison", Justification = "IndexOf(\".\") not a security issue.")]
1405 internal static Activity ParseActivity(Activity parsingContext, string activityName)
1407 if (parsingContext == null)
1408 throw new ArgumentNullException("parsingContext");
1409 if (activityName == null)
1410 throw new ArgumentNullException("activityName");
1412 string currentAtivityName = activityName;
1413 string nextActivityName = string.Empty;
1414 int indexOfDot = activityName.IndexOf(".");
1415 if (indexOfDot != -1)
1417 currentAtivityName = activityName.Substring(0, indexOfDot);
1418 nextActivityName = activityName.Substring(indexOfDot + 1);
1419 if (nextActivityName.Length == 0)
1423 Activity currentActivity = null;
1424 currentActivity = GetActivity(parsingContext, currentAtivityName);
1426 // The check for parsingContext.Parent != null is added here because IsCustomActivity returns true for root activities.
1427 if (currentActivity == null && (parsingContext is CompositeActivity) && parsingContext.Parent != null && Helpers.IsCustomActivity(parsingContext as CompositeActivity))
1428 currentActivity = GetActivity(parsingContext, parsingContext.QualifiedName + "." + currentAtivityName);
1430 if (currentActivity != null)
1432 if (nextActivityName.Length > 0)
1434 if (!(currentActivity is CompositeActivity) || !Helpers.IsCustomActivity(currentActivity as CompositeActivity))
1435 // current activity must be a custom activity, otherwise there should be no dots in the name.
1438 string[] names = nextActivityName.Split('.');
1439 for (int i = 0; i < names.Length; i++)
1441 Activity nextActivity = GetActivity(currentActivity, currentActivity.QualifiedName + "." + names[i]);
1442 if (nextActivity == null || !Helpers.IsActivityLocked(nextActivity))
1445 CompositeActivity declaringActivity = Helpers.GetDeclaringActivity(nextActivity);
1446 if (currentActivity != declaringActivity)
1449 currentActivity = nextActivity;
1452 return currentActivity;
1456 // This activity should always be unlocked, unless if GetChildActivity() is called from
1457 // within the custom activity's companion class, then we don't have the full qualified ID available
1458 // at that time. We allow this to succeed only if the declaring activity is the same as the declaring
1459 // activity of the context activity passed in.
1460 if (Helpers.IsActivityLocked(currentActivity))//.IsLocked)
1462 if (!IsDeclaringActivityMatchesContext(currentActivity, parsingContext))
1466 return currentActivity;
1473 private static Activity GetActivity(Activity containerActivity, string id)
1475 if (containerActivity != null)
1477 Queue activities = new Queue();
1478 activities.Enqueue(containerActivity);
1479 while (activities.Count > 0)
1481 Activity activity = (Activity)activities.Dequeue();
1482 if (activity.Enabled)
1484 if (activity.QualifiedName == id)
1487 if (activity is CompositeActivity)
1489 foreach (Activity child in ((CompositeActivity)activity).Activities)
1490 activities.Enqueue(child);
1498 private static bool IsDeclaringActivityMatchesContext(Activity currentActivity, Activity context)
1500 CompositeActivity declaringContext = context as CompositeActivity;
1502 CompositeActivity declaringActivityOfCurrent = Helpers.GetDeclaringActivity(currentActivity);
1504 // If the context activity is locked and it is a primitive activity
1505 // or NOT a custom activity then we need to find its enclosing
1507 if (Helpers.IsActivityLocked(context) &&
1508 (declaringContext == null || !Helpers.IsCustomActivity(declaringContext))
1510 declaringContext = Helpers.GetDeclaringActivity(context);
1512 if (declaringContext == declaringActivityOfCurrent)