Reminder: All posts in this series can be found here.
Simply, it is a container for services. Services are classes that have a well-known interface, that have instantiations which be stored in service containers, can be obtained from a service provider, and are addressable by type. The ServiceContainer class is a service provider and implements IServiceProvider. You obtain a service by supplying the Type of the service you want to the service provider's GetService method. The ServiceContainer.GetService method is declared like this.
public virtual Object GetService(Type serviceType);
This is how you obtain a a reference to a service in a class derived from DesignSurfaceManager or DesignSurface. The cast is required because GetService returns an Object.
INameCreationService serviceNameCreation = (INameCreationService)(this.GetService(typeof(INameCreationService)));
Both DesignSurfaceManager and DesignSurface implement ServiceContainer. This may appear to lead to confusion, but you do not have to keep track of which container holds what service. One of the nice features of using the DesignSurfaceManager class is that it automatically merges services between it and the DesignSurfaces.
There is no documentation of how to use these multiple implementations, but it makes sense to put general, non-DesignSurface services such as IHelpService, IDesignerEventService, and INameCreationService in the central DesignSurfaceManager ServiceContainer. DesignSurface-specific services such as ISelectionService would logically be with each DesignSurface.ServiceContainer.
MSDN states the following about the DesignSurfaceManager.ServiceContainer Property: The DesignSurfaceManager class provides several design-time services automatically. You can override each of these services by replacing them in the protected ServiceContainer property. To replace a service, override the constructor, call base, and make any changes through the protected ServiceContainer property. All services added to the service container that implement the IDisposable interface are disposed when the design surface manager is disposed. The DesignSurfaceManager class provides the IDesignerEventService interface as the default service. IDesignerEventService provides a global eventing mechanism for designer events. With this mechanism, an application is informed when a designer becomes active. The service provides a collection of designers and a single place where global objects, such as the Properties window, can monitor selection change events.
What is interesting here is that MSDN itself does not state what the default design-time services are. A MSDN Magazine designer hosting article provides a table of the default DesignSurface design-time services. An important part of that table is listing which services are not replaceable due to their interrelationships. I wrote some code to see what services were running in the two containers for the sample application and found the following.
HostSurfaceManager.ServiceContainer Services
--------------------------------------------
IDesignerEventService
INameCreationService
IToolboxServiceHostSurface.ServiceContainer Services
--------------------------------------------
IComponentChangeService
IDesignerEventService
IDesignerHost
IExtenderListService
IExtenderProviderService
IInheritanceService
IMenuCommandService
INameCreationService
IReferenceService
ISelectionService
IToolboxService
ITypeDescriptorFilterService
This list matches almost perfectly with the default design-time service table noted above. It was not surprising to see the three HostSurfaceManager services were also visible from the HostSurface because the System.ComponentModel.Design.DesignSurfaceManager has a small bit of code in its MergedServiceProvider GetService method that looks like the following:
The primary provider for the HostSurface is its own ServiceContainer. The secondary provider for the HostSurface is the HostSurfaceManager.ServiceContainer. As shown in the code snippet, any HostSurface service is preferred over an identical one in the HostSurfaceManager. Any service unavailable in the HostSurface but present in the HostSurfaceManager is accessible as well.Object service = this._primaryProvider.GetService(serviceType); if (service == null) { service = this._secondaryProvider.GetService(serviceType); }
return service;
Print | posted on Monday, October 22, 2007 10:15 PM | Filed Under [ Programming Forms Designer ]
Feedback
No comments posted yet.