Code:
/ FX-1434 / FX-1434 / 1.0 / untmp / whidbey / REDBITS / ndp / fx / src / Designer / Drawing / System / Drawing / Design / ToolboxService.cs / 1 / ToolboxService.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- namespace System.Drawing.Design { using System; using System.Collections; using System.ComponentModel; using System.ComponentModel.Design; using System.Diagnostics; using System.Drawing; using System.Globalization; using System.IO; using System.Reflection; using System.Runtime.Remoting.Lifetime; using System.Runtime.Serialization; using System.Runtime.Serialization.Formatters.Binary; using System.Security; using System.Security.Permissions; using System.Windows.Forms; ////// /// This is a partial implementation of the IToolboxService /// interface. To use this implementation you must /// derive from this class and implement the abstract /// methods. Once implemented, you may add this class /// to your designer application's service container. /// There should be one toolbox service for each /// designer application. /// [System.Security.Permissions.PermissionSetAttribute(System.Security.Permissions.SecurityAction.InheritanceDemand, Name="FullTrust")] [System.Security.Permissions.PermissionSetAttribute(System.Security.Permissions.SecurityAction.LinkDemand, Name="FullTrust")] public abstract class ToolboxService : IToolboxService, IComponentDiscoveryService { private IDesignerEventService _designerEventService; private ArrayList _globalCreators; private Hashtable _designerCreators; // key: designer host, value: ArrayList of ToolboxItemCreators // A cache of the last merge we did to merge designer creators and global creators. private IDesignerHost _lastMergedHost; private ICollection _lastMergedCreators; // DesignerToolboxInfo stores filter and toolbox user information // on a per-designer basis. This is the last one we queried. private DesignerToolboxInfo _lastState; // We maintain a separate app domain to enumerate assemblies without // locking them. // private static DomainProxyObject _domainObject; private static AppDomain _domain; private static ClientSponsor _domainObjectSponsor; ////// /// Retrieves a collection of category name strings. /// These category names correspond to various toolbox /// categories. /// protected abstract CategoryNameCollection CategoryNames { get; } ////// /// Gets or sets the selected category for the toolbox. /// Toolbox items are generally grouped into categories. /// protected abstract string SelectedCategory { get; set; } ////// /// Gets or sets the selected toolbox item. /// protected abstract ToolboxItemContainer SelectedItemContainer {get; set; } ////// /// Creates a new toolbox item container from a toolbox /// item. This allows the implementor the chance to /// provide a derived version of ToolboxItemContainer. /// If the provided IDesignerHost link parameter is /// non-null it indicates that this is a linked toolbox /// item. By default, ToolboxService does not support /// linked items so it will return null for non-null /// link parameters. To provide link support, you should /// override this method to create a derived /// ToolboxItemContainer object that knows how to handle /// links. A "linked" toolbox item is one whose lifetime /// is related to the storage of a particular designer /// host. So, in a typical project system, a designer /// host is associated with a particular file. A /// toobox item linked to a designer host would automatically /// be deleted from the toolbox when the designer host's /// source file is deleted or removed from the project. /// protected virtual ToolboxItemContainer CreateItemContainer(ToolboxItem item, IDesignerHost link) { if (item == null) { throw new ArgumentNullException("item"); } // Default implementation does not support links. if (link != null) { return null; } return new ToolboxItemContainer(item); } ////// /// Creates a new toolbox item container from a data object. The /// data object passed in should contain data obtained from /// a prior call to the ToolboxData property on a toolbox item /// container. /// protected virtual ToolboxItemContainer CreateItemContainer(IDataObject dataObject) { if (dataObject == null) { throw new ArgumentNullException("dataObject"); } return new ToolboxItemContainer(dataObject); } ////// /// This event is raised when the toolbox service detects that /// the toolbox item filter for the actvie designer /// has changed. /// protected virtual void FilterChanged() { } ////// Returns an ICollection of toolbox item creators, or null if there /// is no active creator collection. This will merge global creators /// in with the provided host, if not null. This also caches the /// last provided merged collection because merging takes time. /// private ICollection GetCreatorCollection(IDesignerHost host) { // If not provided a host, we just return the global // creator collection. // if (host == null) { return _globalCreators; } // If we are provided a host, and that host matches the // last request, we returned the last merged set. Otherwise, // we build a new merged set. // if (host != _lastMergedHost) { ICollection creators = _globalCreators; ICollection hostCreators = null; if (_designerCreators != null) { hostCreators = _designerCreators[host] as ICollection; if (hostCreators != null) { int cnt = hostCreators.Count; if (creators != null) { cnt += creators.Count; } ToolboxItemCreator[] newCreators = new ToolboxItemCreator[cnt]; hostCreators.CopyTo(newCreators, 0); if (creators != null) { creators.CopyTo(newCreators, hostCreators.Count); } creators = newCreators; } } _lastMergedCreators = creators; _lastMergedHost = host; } #if DEBUG // For debug builds verify that our caching algorithm didn't miss. // else if (_lastMergedCreators != null) { int debugCount = 0; if (_globalCreators != null) { debugCount += _globalCreators.Count; } if (_designerCreators != null) { ICollection debugCreators = _designerCreators[host] as ICollection; if (debugCreators != null) { debugCount += debugCreators.Count; } } Debug.Assert(_lastMergedCreators.Count == debugCount, "ToolboxItemCreator cache algorithm is broken."); } #endif return _lastMergedCreators; } ////// Determines the type of filter support given two filter collections. /// /// Truth Table: /// /// Root Designer /// Class Mismatch Allow Prevent Require Custom /// Mismatch Y Y Y N Y /// Allow Y Y N Y IsSupported /// Prevent Y N N N N /// Require N Y N Y IsSupported /// Custom Y IsSupported N IsSupported IsSupported /// /// Legend: /// /// Y : The toolbox item will be enabled /// N : The toolbox item will be disabled /// IsSupported: The toolbox item will be enabled only if the method IToolboxUser.IsSupported returns true. /// /// private static FilterSupport GetFilterSupport(ICollection itemFilter, ICollection targetFilter) { FilterSupport support = FilterSupport.Supported; int requireCount = 0; int requireMatch = 0; // If Custom is specified on the designer, then we check to see if the // filter name matches an attribute, or if the filter name is empty. // If either is the case, then we will invoke the designer for custom // support. // foreach(ToolboxItemFilterAttribute attr in itemFilter) { if (support == FilterSupport.NotSupported) { break; } if (attr.FilterType == ToolboxItemFilterType.Require) { // This filter is required. Check that it exists. Require filters // are or-matches. If any one requirement is satisified, you're fine. // requireCount++; foreach(object attrObject in targetFilter) { ToolboxItemFilterAttribute attr2 = attrObject as ToolboxItemFilterAttribute; if (attr2 == null) { continue; } if (attr.Match(attr2)) { requireMatch++; break; } } } else if (attr.FilterType == ToolboxItemFilterType.Prevent) { // This filter should be prevented. Check that it fails. // foreach(object attrObject in targetFilter) { ToolboxItemFilterAttribute attr2 = attrObject as ToolboxItemFilterAttribute; if (attr2 == null) { continue; } if (attr.Match(attr2)) { support = FilterSupport.NotSupported; break; } } } else if (support != FilterSupport.Custom && attr.FilterType == ToolboxItemFilterType.Custom) { if (attr.FilterString.Length == 0) { support = FilterSupport.Custom; } else { foreach(ToolboxItemFilterAttribute attr2 in targetFilter) { if (attr.FilterString.Equals(attr2.FilterString)) { support = FilterSupport.Custom; break; } } } } } // Now, configure Supported based on matching require counts // if (support != FilterSupport.NotSupported && requireCount > 0 && requireMatch == 0) { support = FilterSupport.NotSupported; } // Now, do the same thing for the designer side. Identical check, but from // a different perspective. We also check for the presence of a custom filter // here. // if (support != FilterSupport.NotSupported) { requireCount = 0; requireMatch = 0; foreach(ToolboxItemFilterAttribute attr in targetFilter) { if (support == FilterSupport.NotSupported) { break; } if (attr.FilterType == ToolboxItemFilterType.Require) { // This filter is required. Check that it exists. Require filters // are or-matches. If any one requirement is satisified, you're fine. // requireCount++; foreach(ToolboxItemFilterAttribute attr2 in itemFilter) { if (attr.Match(attr2)) { requireMatch++; break; } } } else if (attr.FilterType == ToolboxItemFilterType.Prevent) { // This filter should be prevented. Check that it fails. // foreach(ToolboxItemFilterAttribute attr2 in itemFilter) { if (attr.Match(attr2)) { support = FilterSupport.NotSupported; break; } } } else if (support != FilterSupport.Custom && attr.FilterType == ToolboxItemFilterType.Custom) { if (attr.FilterString.Length == 0) { support = FilterSupport.Custom; } else { foreach(ToolboxItemFilterAttribute attr2 in itemFilter) { if (attr.FilterString.Equals(attr2.FilterString)) { support = FilterSupport.Custom; break; } } } } } // Now, configure Supported based on matching require counts // if (support != FilterSupport.NotSupported && requireCount > 0 && requireMatch == 0) { support = FilterSupport.NotSupported; } } return support; } ////// /// Retrieves an IList containing all items on the toolbox. /// The items in the list must be ToolboxItemContainer objects. /// If the toolbox implementation is organlized in /// categories, this retrieves a combined list of all /// categories. The list must be read-write. New items /// will be created by calling CreateItem, and then passing /// this newly created item to the Add method of the list. /// protected abstract IList GetItemContainers(); ////// /// Retrieves an IList containing items on the toolbox /// associated with a particular category. If the category does /// not exist this should throw a meaningful exception. /// The items in the list must be ToolboxItemContainer objects. /// The list must be read-write. New items will be /// created by calling CreateItem, and then passing /// this newly created item to the Add method of the list. /// protected abstract IList GetItemContainers(string categoryName); ////// /// Returns a toolbox item associated with the given type, or /// null if the type has no corresponding toolbox item. /// public static ToolboxItem GetToolboxItem(Type toolType) { return GetToolboxItem(toolType, false); } ////// /// Returns a toolbox item associated with the given type, or /// null if the type has no corresponding toolbox item. If nonPublic is true this will search /// for non-public constructors on the type. If false, constructurs need to be public. /// public static ToolboxItem GetToolboxItem(Type toolType, bool nonPublic) { ToolboxItem item = null; if (toolType == null) { throw new ArgumentNullException("toolType"); } if (((nonPublic || toolType.IsPublic) || toolType.IsNestedPublic) && typeof(IComponent).IsAssignableFrom(toolType) && !toolType.IsAbstract) { // Create a toolbox item for this type, if it is supported // ToolboxItemAttribute tba = (ToolboxItemAttribute)TypeDescriptor.GetAttributes(toolType)[typeof(ToolboxItemAttribute)]; if (!tba.IsDefaultAttribute()) { Type itemType = tba.ToolboxItemType; if (itemType != null) { // First, try to find a constructor with Type as a parameter. If that // fails, try the default constructor. // ConstructorInfo ctor = itemType.GetConstructor(new Type[] {typeof(Type)}); if (ctor != null && toolType != null) { item = (ToolboxItem)ctor.Invoke(new object[] {toolType}); } else { ctor = itemType.GetConstructor(new Type[0]); if (ctor != null) { item = (ToolboxItem)ctor.Invoke(new object[0]); item.Initialize(toolType); } } } } else if (!tba.Equals(ToolboxItemAttribute.None) && !toolType.ContainsGenericParameters) { //the default toolboxitem class does not support generics, but we do not stop anyone from specifying thier own //toolboxitem if they really want to. //however, most tools in VS will be filtering generics, so this would be an advanced scenario. item = new ToolboxItem(toolType); } } else if (typeof(ToolboxItem).IsAssignableFrom(toolType)) { // if the type *is* a toolboxitem, just create it.. // item = (ToolboxItem)Activator.CreateInstance(toolType, true); } return item; } ////// /// Returns a collection containing all the toolbox items in the /// given assembly. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly")] // Would be a breaking change. public static ICollection GetToolboxItems(Assembly a, string newCodeBase) { return GetToolboxItems(a, newCodeBase, false); } ////// /// Returns a collection containing all the toolbox items in the /// given assembly. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly")] // Would be a breaking change. public static ICollection GetToolboxItems(Assembly a, string newCodeBase, bool throwOnError) { if (a == null) { throw new ArgumentNullException("a"); } ArrayList items = new ArrayList(); // For GAC installed assemblies, we want to replace the current // assembly name with the SDK path for the assembly, so we are not // relying on specific places within the GAC. // AssemblyName newAssemblyName; if (a.GlobalAssemblyCache) { newAssemblyName = a.GetName(); newAssemblyName.CodeBase = newCodeBase; } else { newAssemblyName = null; } try { foreach(Type type in a.GetTypes()) { // only do IComponent things from here... // if (!typeof(IComponent).IsAssignableFrom(type)) { continue; } // Look for compatible constructors // ConstructorInfo ctor = type.GetConstructor(new Type[0]); if (ctor == null) { ctor = type.GetConstructor(new Type[] {typeof(IContainer)}); } if (ctor == null) { continue; } try { ToolboxItem item = GetToolboxItem(type); if (item != null) { // Now that we have the item, we may need to replace the // assembly name. // if (newAssemblyName != null) { item.AssemblyName = newAssemblyName; } // Finally, this item needs to go in our list. // items.Add(item); } } catch { if (throwOnError) { throw; } // Nothing here. If a toolbox item failed we want to continue searching // the rest of the types. } } } catch { if (throwOnError) { throw; } // Nothing here. If an assembly is missing dependencies it could throw while // we evaluate. Eat it and move on. } return items; } ////// /// Returns a collection containing all the toolbox items in /// the assembly represented by the given assembly name. This /// will only momentarially lock the assembly file. /// public static ICollection GetToolboxItems(AssemblyName an) { return GetToolboxItems(an, false); } ////// /// Returns a collection containing all the toolbox items in /// the assembly represented by the given assembly name. This /// will only momentarially lock the assembly file. /// public static ICollection GetToolboxItems(AssemblyName an, bool throwOnError) { if (_domainObject == null) { _domain = AppDomain.CreateDomain("Assembly Enumeration Domain"); _domainObject = (DomainProxyObject)_domain.CreateInstanceAndUnwrap(typeof(DomainProxyObject).Assembly.FullName, typeof(DomainProxyObject).FullName); _domainObjectSponsor = new ClientSponsor(new TimeSpan(0 /* hours */, 5 /* minutes */, 0 /* seconds */)); _domainObjectSponsor.Register(_domainObject); } byte[] bytes = _domainObject.GetToolboxItems(an, throwOnError); BinaryFormatter f = new BinaryFormatter(); ICollection items = (ICollection)f.Deserialize(new MemoryStream(bytes)); return items; } ////// /// Called to perform a quick check to see if the given data object represents /// a toolbox item. You may pass in an instance of a designer host if /// you want to include custom toolbox item creators the host provides. /// Otherwise, this parameter can be null. /// protected virtual bool IsItemContainer(IDataObject dataObject, IDesignerHost host) { if (dataObject == null) { throw new ArgumentNullException("dataObject"); } if (ToolboxItemContainer.ContainsFormat(dataObject)) { return true; } ICollection creators = GetCreatorCollection(host); if (creators != null) { foreach(ToolboxItemCreator creator in creators) { if (dataObject.GetDataPresent(creator.Format)) { return true; } } } return false; } ////// /// This is a helper method that can be used if a toolbox item container /// is supported by the given designer host. /// protected bool IsItemContainerSupported(ToolboxItemContainer container, IDesignerHost host) { if (container == null) { throw new ArgumentNullException("container"); } if (host == null) { throw new ArgumentNullException("host"); } ICollection creators = GetCreatorCollection(host); _lastState = host.GetService(typeof(DesignerToolboxInfo)) as DesignerToolboxInfo; if (_lastState == null) { _lastState = new DesignerToolboxInfo(this, host); host.AddService(typeof(DesignerToolboxInfo), _lastState); } switch(GetFilterSupport(container.GetFilter(creators), _lastState.Filter)) { case FilterSupport.NotSupported: return false; case FilterSupport.Supported: return true; case FilterSupport.Custom: if (_lastState.ToolboxUser != null) { return _lastState.ToolboxUser.GetToolSupported(container.GetToolboxItem(creators)); } break; } return false; } ////// Called by our DesignerToolboxInfo object to /// notify us when the external designer state /// (filtering, etc) has changed. /// internal void OnDesignerInfoChanged(DesignerToolboxInfo state) { // One of the toolbox item state objects changed. If // it is tied to the currently active designer then // we need to raise our FilterChanged event. // if (_designerEventService == null) { _designerEventService = state.DesignerHost.GetService(typeof(IDesignerEventService)) as IDesignerEventService; } if (_designerEventService != null && _designerEventService.ActiveDesigner == state.DesignerHost) { FilterChanged(); } } /* */ ////// /// Called by the toolbox service when an outside ouser /// has requested that the collection of items should /// be refreshed. If the collection is always live, /// there is no need to provide any implementation here. /// If the collection returned from GetItemContainers /// represents a snapshot of the toolbox items, however, /// this method provides a opportunity to update them. /// protected abstract void Refresh(); ////// /// Called by the toolbox service when an outside /// user has reported that he/she has used the /// selected toolbox item. The default behavior is /// to set the selected item to null. /// protected virtual void SelectedItemContainerUsed() { SelectedItemContainer = null; } ////// /// Called by the toolbox service when an outside /// user has asked to set the cursor for the currently /// selected toolbox item. The default implementation /// sets the cursor to a crosshair and returns true /// if there is a toolbox item selected. It returns /// false if no item is selected. /// protected virtual bool SetCursor() { if (SelectedItemContainer != null) { Cursor.Current = Cursors.Cross; return true; } return false; } ////// /// This unloads any assemblies that were locked /// as a result of calling GetToolboxItems. /// public static void UnloadToolboxItems() { // We are now done with the domain, so release it. // if (_domain != null) { AppDomain deadDomain = _domain; _domainObjectSponsor.Close(); _domainObjectSponsor = null; _domainObject = null; _domain = null; AppDomain.Unload(deadDomain); } } ////// /// Gets the names of all the tool categories currently on the toolbox. /// CategoryNameCollection IToolboxService.CategoryNames { get { return CategoryNames; } } ////// /// Gets the name of the currently selected tool category from the toolbox. /// string IToolboxService.SelectedCategory { get { return SelectedCategory; } set { SelectedCategory = value; } } ////// /// Adds a new toolbox item creator. /// void IToolboxService.AddCreator(ToolboxItemCreatorCallback creator, string format) { if (creator == null) { throw new ArgumentNullException("creator"); } if (format == null) { throw new ArgumentNullException("format"); } if (_globalCreators == null) { _globalCreators = new ArrayList(); } _globalCreators.Add(new ToolboxItemCreator(creator, format)); // We now need to re-query because the list has changed. // _lastMergedHost = null; _lastMergedCreators = null; } ////// /// Adds a new toolbox item creator. /// void IToolboxService.AddCreator(ToolboxItemCreatorCallback creator, string format, IDesignerHost host) { if (creator == null) { throw new ArgumentNullException("creator"); } if (format == null) { throw new ArgumentNullException("format"); } if (host == null) { throw new ArgumentNullException("host"); } if (_designerCreators == null) { _designerCreators = new Hashtable(); } ArrayList list = _designerCreators[host] as ArrayList; if (list == null) { list = new ArrayList(4); _designerCreators[host] = list; } list.Add(new ToolboxItemCreator(creator, format)); // We now need to re-query because the list has changed. // _lastMergedHost = null; _lastMergedCreators = null; } ////// /// Adds a new tool to the toolbox under the default category. /// void IToolboxService.AddLinkedToolboxItem(ToolboxItem toolboxItem, IDesignerHost host) { if (toolboxItem == null) { throw new ArgumentNullException("toolboxItem"); } if (host == null) { throw new ArgumentNullException("host"); } ToolboxItemContainer item = CreateItemContainer(toolboxItem, host); // Item can be null if this service doesn't support linking. // if (item != null) { GetItemContainers(SelectedCategory).Add(item); } } ////// /// Adds a new tool to the toolbox under the specified category. /// void IToolboxService.AddLinkedToolboxItem(ToolboxItem toolboxItem, string category, IDesignerHost host) { if (toolboxItem == null) { throw new ArgumentNullException("toolboxItem"); } if (category == null) { throw new ArgumentNullException("category"); } if (host == null) { throw new ArgumentNullException("host"); } ToolboxItemContainer item = CreateItemContainer(toolboxItem, host); // Item can be null if this service doesn't support linking. // if (item != null) { GetItemContainers(category).Add(item); } } ////// /// Adds a new tool to the toolbox under the default category. /// void IToolboxService.AddToolboxItem(ToolboxItem toolboxItem) { if (toolboxItem == null) { throw new ArgumentNullException("toolboxItem"); } ToolboxItemContainer item = CreateItemContainer(toolboxItem, null); if (item != null) { GetItemContainers(SelectedCategory).Add(item); } } ////// /// Adds a new tool to the toolbox under the specified category. /// void IToolboxService.AddToolboxItem(ToolboxItem toolboxItem, string category) { if (toolboxItem == null) { throw new ArgumentNullException("toolboxItem"); } if (category == null) { throw new ArgumentNullException("category"); } ToolboxItemContainer item = CreateItemContainer(toolboxItem, null); if (item != null) { GetItemContainers(category).Add(item); } } ////// /// Gets a toolbox item from a previously serialized object. /// ToolboxItem IToolboxService.DeserializeToolboxItem(object serializedObject) { if (serializedObject == null) { throw new ArgumentNullException("serializedObject"); } IDataObject dataObject = serializedObject as IDataObject; if (dataObject == null) { dataObject = new DataObject(serializedObject); } ToolboxItemContainer container = CreateItemContainer(dataObject); if (container != null) { return container.GetToolboxItem(GetCreatorCollection(null)); } return null; } ////// /// Gets a toolbox item from a previously serialized object. /// ToolboxItem IToolboxService.DeserializeToolboxItem(object serializedObject, IDesignerHost host) { if (serializedObject == null) { throw new ArgumentNullException("serializedObject"); } if (host == null) { throw new ArgumentNullException("host"); } IDataObject dataObject = serializedObject as IDataObject; if (dataObject == null) { dataObject = new DataObject(serializedObject); } ToolboxItemContainer container = CreateItemContainer(dataObject); if (container != null) { return container.GetToolboxItem(GetCreatorCollection(host)); } return null; } ////// /// Gets the currently selected tool. /// ToolboxItem IToolboxService.GetSelectedToolboxItem() { ToolboxItemContainer container = SelectedItemContainer; if (container != null) { return container.GetToolboxItem(GetCreatorCollection(null)); } return null; } ////// /// Gets the currently selected tool. /// ToolboxItem IToolboxService.GetSelectedToolboxItem(IDesignerHost host) { if (host == null) { throw new ArgumentNullException("host"); } ToolboxItemContainer container = SelectedItemContainer; if (container != null) { return container.GetToolboxItem(GetCreatorCollection(host)); } return null; } ////// /// Gets all .NET Framework tools on the toolbox. /// ToolboxItemCollection IToolboxService.GetToolboxItems() { IList itemContainers = GetItemContainers(); ArrayList items = new ArrayList(itemContainers.Count); ICollection creators = GetCreatorCollection(null); foreach(ToolboxItemContainer container in itemContainers) { ToolboxItem item = container.GetToolboxItem(creators); if (item != null) { items.Add(item); } } ToolboxItem[] itemArray = new ToolboxItem[items.Count]; items.CopyTo(itemArray, 0); return new ToolboxItemCollection(itemArray); } ////// /// Gets all .NET Framework tools on the toolbox. /// ToolboxItemCollection IToolboxService.GetToolboxItems(IDesignerHost host) { if (host == null) { throw new ArgumentNullException("host"); } IList itemContainers = GetItemContainers(); ArrayList items = new ArrayList(itemContainers.Count); ICollection creators = GetCreatorCollection(host); foreach(ToolboxItemContainer container in itemContainers) { ToolboxItem item = container.GetToolboxItem(creators); if (item != null) { items.Add(item); } } ToolboxItem[] itemArray = new ToolboxItem[items.Count]; items.CopyTo(itemArray, 0); return new ToolboxItemCollection(itemArray); } ////// /// Gets all .NET Framework tools on the specified toolbox category. /// ToolboxItemCollection IToolboxService.GetToolboxItems(String category) { if (category == null) { throw new ArgumentNullException("category"); } IList itemContainers = GetItemContainers(category); ArrayList items = new ArrayList(itemContainers.Count); ICollection creators = GetCreatorCollection(null); foreach(ToolboxItemContainer container in itemContainers) { ToolboxItem item = container.GetToolboxItem(creators); if (item != null) { items.Add(item); } } ToolboxItem[] itemArray = new ToolboxItem[items.Count]; items.CopyTo(itemArray, 0); return new ToolboxItemCollection(itemArray); } ////// /// Gets all .NET Framework tools on the specified toolbox category. /// ToolboxItemCollection IToolboxService.GetToolboxItems(String category, IDesignerHost host) { if (category == null) { throw new ArgumentNullException("category"); } if (host == null) { throw new ArgumentNullException("host"); } IList itemContainers = GetItemContainers(category); ArrayList items = new ArrayList(itemContainers.Count); ICollection creators = GetCreatorCollection(host); foreach(ToolboxItemContainer container in itemContainers) { ToolboxItem item = container.GetToolboxItem(creators); if (item != null) { items.Add(item); } } ToolboxItem[] itemArray = new ToolboxItem[items.Count]; items.CopyTo(itemArray, 0); return new ToolboxItemCollection(itemArray); } ////// /// Determines if the given designer host contains a designer that supports the serialized /// toolbox item. This will return false if the designer doesn't support the item, or if the /// serializedObject parameter does not contain a toolbox item. /// bool IToolboxService.IsSupported(object serializedObject, IDesignerHost host) { if (serializedObject == null) { throw new ArgumentNullException("serializedObject"); } if (host == null) { throw new ArgumentNullException("host"); } IDataObject dataObject = serializedObject as IDataObject; if (dataObject == null) { dataObject = new DataObject(serializedObject); } // First, is this even a valid serialized object? // if (!IsItemContainer(dataObject, host)) { return false; } ToolboxItemContainer container = CreateItemContainer(dataObject); // Second, identify the filter that the host is using. If // the filter matches, then we are OK. // return IsItemContainerSupported(container, host); } ////// /// Determines if the serialized toolbox item contains a matching collection of filter attributes. /// This will return false if the serializedObject parameter doesn't contain a toolbox item, /// or if the collection of filter attributes does not match. /// bool IToolboxService.IsSupported(object serializedObject, ICollection filterAttributes) { if (serializedObject == null) { throw new ArgumentNullException("serializedObject"); } if (filterAttributes == null) { throw new ArgumentNullException("filterAttributes"); } IDataObject dataObject = serializedObject as IDataObject; if (dataObject == null) { dataObject = new DataObject(serializedObject); } // First, is this even a valid serialized object? // if (!IsItemContainer(dataObject, null)) { return false; } ToolboxItemContainer container = CreateItemContainer(dataObject); return GetFilterSupport(container.GetFilter(GetCreatorCollection(null)), filterAttributes) == FilterSupport.Supported; } ////// /// Gets a value indicating whether the specified object contains a serialized toolbox item. /// bool IToolboxService.IsToolboxItem(object serializedObject) { if (serializedObject == null) { throw new ArgumentNullException("serializedObject"); } IDataObject dataObject = serializedObject as IDataObject; if (dataObject == null) { dataObject = new DataObject(serializedObject); } return IsItemContainer(dataObject, null); } ////// /// Gets a value indicating whether the specified object contains a serialized toolbox item. /// bool IToolboxService.IsToolboxItem(object serializedObject, IDesignerHost host) { if (serializedObject == null) { throw new ArgumentNullException("serializedObject"); } if (host == null) { throw new ArgumentNullException("host"); } IDataObject dataObject = serializedObject as IDataObject; if (dataObject == null) { dataObject = new DataObject(serializedObject); } return IsItemContainer(dataObject, host); } ////// /// Refreshes the state of the toolbox items. /// void IToolboxService.Refresh() { Refresh(); } ////// /// Removes a previously added toolbox creator. /// void IToolboxService.RemoveCreator(string format) { if (format == null) { throw new ArgumentNullException("format"); } if (_globalCreators != null) { for (int i = 0; i < _globalCreators.Count; i++) { ToolboxItemCreator creator = _globalCreators[i] as ToolboxItemCreator; if (creator.Format.Equals(format)) { _globalCreators.RemoveAt(i); // We now need to re-query because the list has changed. // _lastMergedHost = null; _lastMergedCreators = null; return; } } } } ////// /// Removes a previously added toolbox creator. /// void IToolboxService.RemoveCreator(string format, IDesignerHost host) { if (format == null) { throw new ArgumentNullException("format"); } if (host == null) { throw new ArgumentNullException("host"); } if (_designerCreators != null) { ArrayList list = _designerCreators[host] as ArrayList; if (list != null) { for (int i = 0; i < list.Count; i++) { ToolboxItemCreator creator = list[i] as ToolboxItemCreator; if (creator.Format.Equals(format)) { list.RemoveAt(i); // We now need to re-query because the list has changed. // _lastMergedHost = null; _lastMergedCreators = null; return; } } } } } ////// /// Removes the specified tool from the toolbox. /// void IToolboxService.RemoveToolboxItem(ToolboxItem toolboxItem) { if (toolboxItem == null) { throw new ArgumentNullException("toolboxItem"); } GetItemContainers().Remove(CreateItemContainer(toolboxItem, null)); } ////// /// Removes the specified tool from the toolbox. /// void IToolboxService.RemoveToolboxItem(ToolboxItem toolboxItem, string category) { if (toolboxItem == null) { throw new ArgumentNullException("toolboxItem"); } if (category == null) { throw new ArgumentNullException("category"); } GetItemContainers(category).Remove(CreateItemContainer(toolboxItem, null)); } ////// /// Notifies the toolbox that the selected tool has been used. /// void IToolboxService.SelectedToolboxItemUsed() { SelectedItemContainerUsed(); } ////// /// Takes the given toolbox item and serializes it to a persistent object. This object can then /// be stored in a stream or passed around in a drag and drop or clipboard operation. /// object IToolboxService.SerializeToolboxItem(ToolboxItem toolboxItem) { if (toolboxItem == null) { throw new ArgumentNullException("toolboxItem"); } return CreateItemContainer(toolboxItem, null).ToolboxData; } ////// /// Sets the current application's cursor to a cursor that represents the /// currently selected tool. /// bool IToolboxService.SetCursor() { return SetCursor(); } ////// /// Sets the currently selected tool in the toolbox. /// void IToolboxService.SetSelectedToolboxItem(ToolboxItem toolboxItem) { if (toolboxItem != null) { SelectedItemContainer = CreateItemContainer(toolboxItem, null); } else { SelectedItemContainer = null; } } ///ICollection IComponentDiscoveryService.GetComponentTypes(IDesignerHost designerHost, Type baseType) { Hashtable types = new Hashtable(); ToolboxItemCollection items = ((IToolboxService)this).GetToolboxItems(); if (items != null) { Type componentType = typeof(IComponent); foreach (ToolboxItem item in items) { Type t = item.GetType(designerHost); if (t != null) { if (componentType.IsAssignableFrom(t) == false) { continue; } if ((baseType != null) && (baseType.IsAssignableFrom(t) == false)) { continue; } types[t] = t; } } } return types.Values; } /// /// Proxy object to allow us to do cross-domain calls. /// private class DomainProxyObject : MarshalByRefObject { // [....] : Changed this from a stream to a byte[]. Remoting bug // VSWhidbey 90430 causes streams to be marshaled incorrectly across the boundary. // [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2001:AvoidCallingProblematicMethods")] [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1801:AvoidUnusedParameters")] [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2102:CatchNonClsCompliantExceptionsInGeneralHandlers")] internal byte[] GetToolboxItems(AssemblyName an, bool throwOnError) { // Load the assembly here. We are running in a different // app domain, so we can load. When we're finished and // we return, the caller will unload the domain and free // the file. // Assembly assembly = null; try { assembly = Assembly.Load(an); } catch (FileNotFoundException) { } catch (BadImageFormatException) { } catch (IOException) { } if (assembly == null && an.CodeBase != null) { assembly = Assembly.LoadFrom(new System.Uri(an.CodeBase).LocalPath); } if (assembly == null) { throw new ArgumentException(SR.GetString(SR.ToolboxServiceAssemblyNotFound, an.FullName)); } ICollection items = null; try { items = ToolboxService.GetToolboxItems(assembly, null, throwOnError); } catch (Exception e) { //we have to convert the exception if its a ReflectionTypeLoadException ReflectionTypeLoadException typeloadex = e as ReflectionTypeLoadException; if (typeloadex != null) { //remove the types so we don't try to load them when going to the main domain. throw new ReflectionTypeLoadException(null, typeloadex.LoaderExceptions, typeloadex.Message); } //otherwise, we can just throw the original exception. throw; } BinaryFormatter formatter = new BinaryFormatter(); MemoryStream stream = new MemoryStream(); formatter.Serialize(stream, items); stream.Close(); return stream.GetBuffer(); } } ////// Private enum that identifies the level of filter /// support. /// private enum FilterSupport { NotSupported, Supported, Custom } } ////// /// The ToolboxItemCreator class encapsulates toolbox /// item crator callbacks. These callbacks are used by /// designers to provide ways to create toolbox items /// for custom data objects. /// public sealed class ToolboxItemCreator { private ToolboxItemCreatorCallback _callback; private string _format; internal ToolboxItemCreator(ToolboxItemCreatorCallback callback, string format) { _callback = callback; _format = format; } ////// /// Creates a new toolbox item given a /// data object. This may raise an exception /// if the data object does not contain /// data for the supported format. /// public ToolboxItem Create(IDataObject data) { return _callback(data, _format); } ////// /// The data format that this toolbox item /// creator supports. /// public string Format { get { return _format; } } } ////// /// The ToolboxItemContainer class contains a toolbox /// item and can convert a toolbox item to a data object /// and back. /// [Serializable] public class ToolboxItemContainer : ISerializable { private const string _localClipboardFormat = "CF_TOOLBOXITEMCONTAINER"; private const string _itemClipboardFormat = "CF_TOOLBOXITEMCONTAINER_CONTENTS"; private const string _hashClipboardFormat = "CF_TOOLBOXITEMCONTAINER_HASH"; private const string _serializationFormats = "TbxIC_DataObjectFormats"; private const string _serializationValues = "TbxIC_DataObjectValues"; private const short _clipboardVersion = 1; private int _hashCode; private ToolboxItem _toolboxItem; private IDataObject _dataObject; private ICollection _filter; ////// /// Serialization constructor. ToolboxItemContainers /// can be serialized. Note that generally it is not /// necessary to override the serialization mechanism /// for a toolbox item container. Toolbox item /// containers implement serialization by saving the /// IDataObject returned from ToolboxData, so when /// overriding ToolboxData and providing your own /// custom data this data will be included with /// the default ISerializable implementation. You /// would want to override the default serialization /// implementation only if you intend to store /// private details about this toolbox item /// container that should not be exposed through /// the public data object. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1801:AvoidUnusedParameters")] protected ToolboxItemContainer(SerializationInfo info, StreamingContext context) { string[] formats = (string[])info.GetValue(_serializationFormats, typeof(string[])); object[] data = (object[])info.GetValue(_serializationValues, typeof(object[])); Debug.Assert(formats.Length == data.Length, "Array mismatch in serialization"); DataObject d = new DataObject(); for (int i = 0; i < formats.Length; i++) { d.SetData(formats[i], data[i]); } _dataObject = d; } ////// /// Creates a new ToolboxItemContainer object from /// a toolbox item. /// public ToolboxItemContainer(ToolboxItem item) { if (item == null) { throw new ArgumentNullException("item"); } _toolboxItem = item; UpdateFilter(item); _hashCode = item.DisplayName.GetHashCode(); if (item.AssemblyName != null) { _hashCode ^= item.AssemblyName.GetHashCode(); } if (item.TypeName != null) { _hashCode ^= item.TypeName.GetHashCode(); } if (_hashCode == 0) { _hashCode = item.DisplayName.GetHashCode(); } } ////// /// Creates a new ToolboxItemContainer object from an /// IDataObject. The data object can contain /// data provided by the ToolboxItemContainer class, or it /// can contain data that can be read by one /// of the toolbox item creators that have /// been supplied by the user. /// public ToolboxItemContainer(IDataObject data) { if (data == null) { throw new ArgumentNullException("data"); } _dataObject = data; } ////// /// Returns true if the underlying toolbox item has been deserialized. /// public bool IsCreated { get { return (_toolboxItem != null); } } ////// /// Returns true if the toolbox item contained in this /// container has been marked as transient. /// public bool IsTransient { get { if (_toolboxItem != null) { return _toolboxItem.IsTransient; } // If the toolbox item is already persisted, then // it must not have been transient. return false; } } ////// /// The serialized version of the toolbox item. /// This data object can be used by an application /// to store this toolbox item. This data object /// will be fabricated from the toolbox item if /// necessary. Implementors may override this to /// provide additional storage information in the /// data object. /// public virtual IDataObject ToolboxData { get { if (_dataObject == null) { MemoryStream stream = new MemoryStream(); DataObject d = new DataObject(); BinaryWriter writer = new BinaryWriter(stream); writer.Write(_clipboardVersion); writer.Write((short)_filter.Count); foreach (ToolboxItemFilterAttribute attr in _filter) { writer.Write(attr.FilterString); writer.Write((short)attr.FilterType); } writer.Flush(); stream.Close(); d.SetData(_localClipboardFormat, stream.GetBuffer()); d.SetData(_hashClipboardFormat, _hashCode); // Now it's time for the toolbox item itself. We want // to defer actually serializing the toolbox item until // we need to save this to disk, but we want to ensure that // when we load it up at a later date we can recover the item // if it in a non-gac assembly. So we have a wrapper object // that implements ISerializable to handle this for us. // d.SetData(_itemClipboardFormat, new ToolboxItemSerializer(_toolboxItem)); _dataObject = d; } return _dataObject; } } ////// /// This method is called to update the containers filter with the filter from the item. /// This should be called when the toolbox item was modified (or configured) or if a new TypeDescriptionProvider was /// added such that the filter will be changed. /// public void UpdateFilter(ToolboxItem item) { _filter = MergeFilter(item); } ////// This will determine if the data object /// contains our clipboard format. /// internal static bool ContainsFormat(IDataObject dataObject) { return dataObject.GetDataPresent(_localClipboardFormat); } ////// /// Equals override for this class /// public override bool Equals(object obj) { ToolboxItemContainer them = obj as ToolboxItemContainer; if (them == this) { return true; } if (them == null) { return false; } if (this._toolboxItem != null && them._toolboxItem != null && this._toolboxItem.Equals(them._toolboxItem)) { return true; } if (this._dataObject != null && them._dataObject != null && this._dataObject.Equals(them._dataObject)) { return true; } ToolboxItem ourItem = GetToolboxItem(null); ToolboxItem theirItem = them.GetToolboxItem(null); if (ourItem != null && theirItem != null) { return ourItem.Equals(theirItem); } return false; } ////// /// The types stored in a toolbox item may have /// a filter associated with them. Filters can be /// used to restrict the tools that can be placed /// on designers. The objects in this collection are /// all instances of ToolboxItemFilterAttribute. /// public virtual ICollection GetFilter(ICollection creators) { ICollection filter = _filter; if (_filter == null) { if (_dataObject.GetDataPresent(_localClipboardFormat)) { // Our own private format is in the data object. // This format contains filter data, so we just // need to pull it out. byte[] bytes = (byte[])_dataObject.GetData(_localClipboardFormat); if (bytes != null) { // If the stream is null, that could mean that we could not extract it. This is essentially // a "dead" toolbox item BinaryReader reader = new BinaryReader(new MemoryStream(bytes)); short version = reader.ReadInt16(); if (version != _clipboardVersion) { Debug.Fail("Toolbox item version mismatch. Toolbox database contains version " + version.ToString(CultureInfo.InvariantCulture) + " and current codebase expects version " + _clipboardVersion.ToString(CultureInfo.InvariantCulture)); _filter = new ToolboxItemFilterAttribute[0]; } else { short filterCount = reader.ReadInt16(); ToolboxItemFilterAttribute[] filterArray = new ToolboxItemFilterAttribute[filterCount]; for (short i = 0; i < filterCount; i++) { string filterName = reader.ReadString(); short filterValue = reader.ReadInt16(); filterArray[i] = new ToolboxItemFilterAttribute(filterName, (ToolboxItemFilterType)filterValue); } _filter = filterArray; } } else { _filter = new ToolboxItemFilterAttribute[0]; } filter = _filter; } else { // We don't recognize the format of this data object. // Ask one or more creators if it does. if (creators != null) { foreach (ToolboxItemCreator creator in creators) { if (_dataObject.GetDataPresent(creator.Format)) { ToolboxItem item = creator.Create(_dataObject); if (item != null) { filter = MergeFilter(item); break; } } } } } } return filter; } ////// /// Override of hash code /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1808:AvoidCallsThatBoxValueTypes")] public override int GetHashCode() { // Recover the hash code we saved into the data object. if (_hashCode == 0) { if (_dataObject != null && _dataObject.GetDataPresent(_hashClipboardFormat)) { _hashCode = (int)_dataObject.GetData(_hashClipboardFormat); } } // If we failed, hash against our object identity. if (_hashCode == 0) { _hashCode = base.GetHashCode(); } return _hashCode; } ////// /// Protected implementation of ISerializable. /// ToolboxItemContainers can be serialized. /// Note that generally it is not necessary to /// override the serialization mechanism /// for a toolbox item container. Toolbox item /// containers implement serialization by saving the /// IDataObject returned from ToolboxData, so when /// overriding ToolboxData and providing your own /// custom data this data will be included with /// the default ISerializable implementation. You /// would want to override the default serialization /// implementation only if you intend to store /// private details about this toolbox item /// container that should not be exposed through /// the public data object. /// [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.SerializationFormatter)] protected virtual void GetObjectData(SerializationInfo info, StreamingContext context) { IDataObject d = ToolboxData; string[] formats = d.GetFormats(); object[] data = new object[formats.Length]; for (int i = 0; i < data.Length; i++) { data[i] = d.GetData(formats[i]); Debug.Assert(data[i] != null, "Data format contained within toolbox " + formats[i] + " does not implement serializable data?"); } info.AddValue(_serializationFormats, formats); info.AddValue(_serializationValues, data); } ////// /// This will retrieve the toolbox item stored in /// this ToolboxItemContainer class. The creators /// argument supplies a collection of toolbox item /// creators that can be used in case the container /// is unable to create the toolbox item itself. /// Iimplementors may override this to provide custom /// deserialization of the data object. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")] public virtual ToolboxItem GetToolboxItem(ICollection creators) { ToolboxItem item = _toolboxItem; if (_toolboxItem == null) { Debug.Assert(_dataObject != null, "Should always have a data object"); if (_dataObject.GetDataPresent(_itemClipboardFormat)) { // Our own private data format is in the data object. // This format corresponds directly to a toolbox item, // so all we need to do is deserialize it. string exceptionString = null; try { ToolboxItemSerializer s = (ToolboxItemSerializer)_dataObject.GetData(_itemClipboardFormat); _toolboxItem = s.ToolboxItem; } catch (Exception ex) { exceptionString = ex.Message; } catch { Debug.Fail("What is this non CLS exception doing here?!?"); } if (_toolboxItem == null) { Debug.Fail("Toolbox item is either out of date or bogus. We were unable to convert the data object to an item. Does your toolbox need to be reset?"); _toolboxItem = new BrokenToolboxItem(exceptionString); } item = _toolboxItem; } else { // This is an unknown format. Ask our creator collection if // any of them support the format. If they do, ask them to // create a toolbox item. Because the list of creators // depends on the active designer, we do not stash the // toolbox item in our member variable here. It is // considered to be transient. if (creators != null) { foreach (ToolboxItemCreator creator in creators) { if (_dataObject.GetDataPresent(creator.Format)) { item = creator.Create(_dataObject); if (item != null) { break; } } } } } } return item; } ////// This is a helper method that merges the filter from the /// toolbox item along with filter attributes on the item itself. /// private static ICollection MergeFilter(ToolboxItem item) { ICollection existingFilter = item.Filter; ArrayList itemFilter = new ArrayList(); foreach (Attribute a in TypeDescriptor.GetAttributes(item)) { if (a is ToolboxItemFilterAttribute) { itemFilter.Add(a); } } ICollection finalFilter; if (existingFilter == null || existingFilter.Count == 0) { finalFilter = itemFilter; } else { if (itemFilter.Count > 0) { Hashtable hash = new Hashtable(itemFilter.Count + existingFilter.Count); foreach (Attribute a in itemFilter) { hash[a.TypeId] = a; } foreach (Attribute a in existingFilter) { hash[a.TypeId] = a; } ToolboxItemFilterAttribute[] filter = new ToolboxItemFilterAttribute[hash.Values.Count]; hash.Values.CopyTo(filter, 0); finalFilter = filter; } else { finalFilter = existingFilter; } } return finalFilter; } ////// /// Serialization method. We make this private because the only time /// we serialize this class is when enumerating assemblies, and there /// we never create instances of derived classes. /// [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.SerializationFormatter)] void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) { GetObjectData(info, context); } ////// BrokenToolboxItem is a placeholder for a toolbox item we failed to create. /// It sits silently as a simple component until someone asks to create an instance /// of the objects within it, and then it displays an error to the user. /// private class BrokenToolboxItem : ToolboxItem { private string _exceptionString; [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")] public BrokenToolboxItem(string exceptionString) : base(typeof(Component)) { _exceptionString = exceptionString; Lock(); } protected override IComponent[] CreateComponentsCore(IDesignerHost host) { if (_exceptionString != null) { throw new InvalidOperationException(SR.GetString(SR.ToolboxServiceBadToolboxItemWithException, _exceptionString)); } else { throw new InvalidOperationException(SR.GetString(SR.ToolboxServiceBadToolboxItem)); } } } ////// This class serializes a toolbox item. It prefixes the toolbox item with /// assembly information so that when the item is deseralized it can be loaded /// from the assembly, even if that assembly is not in the GAC. /// [Serializable] private sealed class ToolboxItemSerializer : ISerializable { private const string _assemblyNameKey = "AssemblyName"; private const string _streamKey = "Stream"; private static BinaryFormatter _formatter; private ToolboxItem _toolboxItem; ////// internal ToolboxItemSerializer(ToolboxItem toolboxItem) { _toolboxItem = toolboxItem; } ////// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1801:AvoidUnusedParameters")] private ToolboxItemSerializer(SerializationInfo info, StreamingContext context) { AssemblyName name = (AssemblyName)info.GetValue(_assemblyNameKey, typeof(AssemblyName)); byte[] bytes = (byte[])info.GetValue(_streamKey, typeof(byte[])); if (_formatter == null) { _formatter = new BinaryFormatter(); } SerializationBinder oldBinder = _formatter.Binder; _formatter.Binder = new ToolboxSerializationBinder(name); try { _toolboxItem = (ToolboxItem)_formatter.Deserialize(new MemoryStream(bytes)); } finally { _formatter.Binder = oldBinder; } } ////// internal ToolboxItem ToolboxItem { get { return _toolboxItem; } } ////// void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) { if (_formatter == null) { _formatter = new BinaryFormatter(); } MemoryStream stream = new MemoryStream(); _formatter.Serialize(stream, _toolboxItem); stream.Close(); info.AddValue(_assemblyNameKey, _toolboxItem.GetType().Assembly.GetName()); info.AddValue(_streamKey, stream.GetBuffer()); } } ////// Simple serialization binder that is used to load up toolbox items from /// assemblies that are not stored in the GAC. /// private class ToolboxSerializationBinder : SerializationBinder { private Hashtable _assemblies; private AssemblyName _name; private string _namePart; ////// Create a new toolbox serialization binder. /// public ToolboxSerializationBinder(AssemblyName name) { _assemblies = new Hashtable(); _name = name; _namePart = name.Name + ","; } ////// Takes a type name and creates a type. If it cannot match /// the type it returns null. /// [ System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2001:AvoidCallingProblematicMethods"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1307:SpecifyStringComparison") ] public override Type BindToType(string assemblyName, string typeName) { Assembly assembly = (Assembly)_assemblies[assemblyName]; if (assembly == null) { // Try the normal assembly load first. // try { assembly = Assembly.Load(assemblyName); } catch (FileNotFoundException) { } catch (BadImageFormatException) { } catch (IOException) { } if (assembly == null) { AssemblyName an; // Try our stashed assembly name. if (assemblyName.StartsWith(_namePart)) { an = _name; try { assembly = Assembly.Load(an); } catch (FileNotFoundException) { } catch (BadImageFormatException) { } catch (IOException) { } } else { an = new AssemblyName(assemblyName); } // Finally, load via codebase. // if (assembly == null) { string codeBase = an.CodeBase; if (codeBase != null && codeBase.Length > 0 && File.Exists(codeBase)) { assembly = Assembly.LoadFrom(codeBase); } } } if (assembly != null) { _assemblies[assemblyName] = assembly; } } if (assembly != null) { return assembly.GetType(typeName); } // Binder couldn't handle it, let the default loader take over. return null; } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- XmlObjectSerializerWriteContextComplex.cs
- ClientSession.cs
- InputDevice.cs
- EncryptedKey.cs
- TableLayoutPanelCellPosition.cs
- FacetDescriptionElement.cs
- XmlObjectSerializerReadContextComplexJson.cs
- EncodingTable.cs
- WmfPlaceableFileHeader.cs
- SignatureDescription.cs
- UnaryExpression.cs
- OleDbParameter.cs
- ObjectAnimationBase.cs
- UmAlQuraCalendar.cs
- HttpModuleAction.cs
- SafeCancelMibChangeNotify.cs
- IteratorFilter.cs
- ImageKeyConverter.cs
- SqlCacheDependencyDatabaseCollection.cs
- NativeRightsManagementAPIsStructures.cs
- HuffModule.cs
- CornerRadiusConverter.cs
- JavaScriptString.cs
- RNGCryptoServiceProvider.cs
- ControlAdapter.cs
- FieldDescriptor.cs
- DbModificationClause.cs
- base64Transforms.cs
- BamlLocalizerErrorNotifyEventArgs.cs
- ProgressChangedEventArgs.cs
- PartialToken.cs
- Path.cs
- CodeGotoStatement.cs
- CalloutQueueItem.cs
- RuntimeCompatibilityAttribute.cs
- AdRotator.cs
- FieldToken.cs
- ContentType.cs
- Properties.cs
- DoubleLinkList.cs
- CriticalHandle.cs
- Popup.cs
- PeerNameRecordCollection.cs
- DefaultDiscoveryServiceExtension.cs
- NamespaceCollection.cs
- CommandEventArgs.cs
- BamlLocalizationDictionary.cs
- SqlServer2KCompatibilityAnnotation.cs
- SimpleMailWebEventProvider.cs
- NetworkInformationException.cs
- Array.cs
- Module.cs
- AudioFileOut.cs
- _SslStream.cs
- PeerNearMe.cs
- StaticResourceExtension.cs
- BufferedGraphics.cs
- DesignerDataSchemaClass.cs
- ValuePattern.cs
- DataGridViewToolTip.cs
- BooleanFacetDescriptionElement.cs
- BitmapSizeOptions.cs
- WebReferencesBuildProvider.cs
- GridViewRowEventArgs.cs
- WebPartUtil.cs
- WsdlExporter.cs
- DataGridSortingEventArgs.cs
- DefaultSerializationProviderAttribute.cs
- ZoneMembershipCondition.cs
- ContextProperty.cs
- DescendentsWalkerBase.cs
- FontSourceCollection.cs
- HtmlValidatorAdapter.cs
- ApplicationHost.cs
- DateBoldEvent.cs
- DataGridLinkButton.cs
- Thread.cs
- DataGridViewCellStyleChangedEventArgs.cs
- shaperfactoryquerycachekey.cs
- SmtpSection.cs
- WindowsStreamSecurityUpgradeProvider.cs
- HttpApplicationFactory.cs
- DoubleLinkList.cs
- DataSourceDesigner.cs
- RangeValidator.cs
- TableColumn.cs
- ExpressionBuilderContext.cs
- Bits.cs
- ReadOnlyDataSource.cs
- SessionPageStatePersister.cs
- Polyline.cs
- ParseChildrenAsPropertiesAttribute.cs
- NetworkStream.cs
- InstanceKeyView.cs
- DataFormats.cs
- DragStartedEventArgs.cs
- StorageModelBuildProvider.cs
- InputLangChangeEvent.cs
- ProxyWebPartConnectionCollection.cs
- _LoggingObject.cs