IServiceContainer Interface
Assembly: System (in system.dll)
'Declaration <ComVisibleAttribute(True)> _ Public Interface IServiceContainer Inherits IServiceProvider 'Usage Dim instance As IServiceContainer
/** @attribute ComVisibleAttribute(true) */ public interface IServiceContainer extends IServiceProvider
ComVisibleAttribute(true) public interface IServiceContainer extends IServiceProvider
Not applicable.
A service container is, by definition, a service provider. In addition to providing services, it also provides a mechanism for adding and removing services. Services are a foundation of the .NET Framework design-time architecture. Services provide design-time objects access to specific features and methods implemented by a service object that provides a service or services.
To obtain a service at design time, call the GetService method of a component sited in design mode. Designers and other objects can add or remove services at design time through the IDesignerHost interface.
Service containers can be contained by other service containers, forming a tree of service containers. By default, the IServiceContainer interface adds services to the closest service container. When a service is added, it can be added with instructions to promote it. When a service is promoted, it is added to any parent service container, on up until the top of the service container tree is reached. This allows a designer to provide a global service that other objects in the process can use.
The following code example contains the code for a Form that is configured to demonstrate the behavior of a network of linked service containers.
Imports System Imports System.Drawing Imports System.Collections Imports System.ComponentModel Imports System.ComponentModel.Design Imports System.Windows.Forms Imports System.Windows.Forms.Design ' This sample contains a Form class that is configured to demonstrate ' the behavior of a network of linked service containers. ' Notes regarding this IServiceContainer and IServiceProvider implementation: ' ' When implementing the IServiceContainer interface, you may want to ' implement support for a linked service container system ' which enables access to and sharing of services throughout a ' container tree or network. ' ' To effectively share a service, a GetService, AddService or ' RemoveService method must be able to locate a service ' that has been added to a shared service container tree or network. ' ' One simple approach to sharing services, suitable for container networks ' where each container has one parent and the tree has ' one parentless container, is to store services only at the top node ' (the root or grandparent) of a tree. ' ' To store services in the root node of a tree, two types of ' consistencies must be maintained in the implementation: ' ' > The GetService, AddService and RemoveService implementations ' must access the root through some mechanism. ' The ServiceContainerControl's implementations of these ' standard IServiceContainer methods call ' the same method of a parent container, if the container ' has been parented, to route methods to the root. ' ' > The services must be maintained at the root of the tree; ' therefore any new child's services should be copied to the root. ' ServiceContainerControl provides an example user control implmentation ' of the IServiceContainer interface. This implementation of ' IServiceContainer supports a root-node linked service distribution, ' access and removal architecture. Public Class ServiceContainerControl Inherits System.Windows.Forms.UserControl Implements IServiceContainer ' List of service instances sorted by key of service type's full name. Private localServices As SortedList ' List contains the Type for each service sorted by each service type's full name. Private localServiceTypes As SortedList ' The parent IServiceContainer, or null. Private parentServiceContainer As IServiceContainer Public Property serviceParent() As IServiceContainer Get Return parentServiceContainer End Get Set(ByVal Value As IServiceContainer) parentServiceContainer = Value ' Move any services to parent. Dim i As Integer For i = 0 To localServices.Count - 1 parentServiceContainer.AddService( _ CType(localServiceTypes.GetByIndex(i), Type), _ localServices.GetByIndex(i)) Next i localServices.Clear() localServiceTypes.Clear() End Set End Property ' The current state of the control, reflecting whether it has ' obtained or provided a text service. Private state_ As TextServiceState Public Property state() As TextServiceState Get Return state_ End Get Set(ByVal Value As TextServiceState) If CType(Value, TextServiceState) = _ TextServiceState.ServiceProvided Then Me.BackColor = Color.LightGreen ElseIf CType(Value, TextServiceState) = _ TextServiceState.ServiceNotObtained Then Me.BackColor = Color.White ElseIf CType(Value, TextServiceState) = _ TextServiceState.ServiceObtained Then Me.BackColor = Color.LightBlue ElseIf CType(Value, TextServiceState) = _ TextServiceState.ServiceNotFound Then Me.BackColor = Color.SeaShell End If state_ = Value End Set End Property ' Parent form reference for main program function access. Private Shadows parent As ServiceForm ' String for label displayed on the control to indicate ' the control's current service-related configuration state. Public label As String Public Sub New(ByVal size As Size, ByVal location As Point, _ ByVal parent As ServiceForm) MyClass.New(Nothing, size, location, parent) End Sub Public Sub New(ByVal ParentServiceContainer As IServiceContainer, _ ByVal size As Size, ByVal location As Point, ByVal parent As ServiceForm) Me.state_ = TextServiceState.ServiceNotObtained localServices = New SortedList() localServiceTypes = New SortedList() Me.BackColor = Color.Beige Me.label = String.Empty Me.Size = size Me.Location = location Me.parent = parent Me.serviceParent = ParentServiceContainer ' If a parent is specified, set the parent property of this ' linkable IServiceContainer implementation. If (ParentServiceContainer IsNot Nothing) Then serviceParent = ParentServiceContainer End If End Sub ' IServiceProvider.GetService implementation for a linked ' service container architecture. Public Shadows Function GetService(ByVal serviceType As System.Type) As Object Implements IServiceProvider.GetService If (parentServiceContainer IsNot Nothing) Then Return parentServiceContainer.GetService(serviceType) End If Dim serviceInstance As Object = localServices(serviceType.FullName) If serviceInstance Is Nothing Then Return Nothing ElseIf serviceInstance.GetType() Is GetType(ServiceCreatorCallback) Then ' If service instance is a ServiceCreatorCallback, invoke it to create the service Return CType(serviceInstance, ServiceCreatorCallback)(Me, serviceType) End If Return serviceInstance End Function ' IServiceContainer.AddService implementation for a linked ' service container architecture. Public Overloads Sub AddService(ByVal serviceType As System.Type, ByVal callback As System.ComponentModel.Design.ServiceCreatorCallback, ByVal promote As Boolean) Implements IServiceContainer.AddService If promote AndAlso (parentServiceContainer IsNot Nothing) Then parentServiceContainer.AddService(serviceType, callback, True) Else localServiceTypes(serviceType.FullName) = serviceType localServices(serviceType.FullName) = callback End If End Sub ' IServiceContainer.AddService implementation for a linked ' service container architecture. Public Overloads Sub AddService(ByVal serviceType As System.Type, _ ByVal callback As System.ComponentModel.Design.ServiceCreatorCallback) _ Implements IServiceContainer.AddService AddService(serviceType, callback, True) End Sub ' IServiceContainer.AddService implementation for a linked ' service container architecture. Public Overloads Sub AddService(ByVal serviceType As System.Type, _ ByVal serviceInstance As Object, ByVal promote As Boolean) _ Implements IServiceContainer.AddService If promote AndAlso (parentServiceContainer IsNot Nothing) Then parentServiceContainer.AddService(serviceType, serviceInstance, True) Else localServiceTypes(serviceType.FullName) = serviceType localServices(serviceType.FullName) = serviceInstance End If End Sub ' IServiceContainer.AddService (defaults to promote service addition). Public Overloads Sub AddService(ByVal serviceType As System.Type, _ ByVal serviceInstance As Object) Implements IServiceContainer.AddService AddService(serviceType, serviceInstance, True) End Sub ' IServiceContainer.RemoveService implementation for a linked ' service container architecture. Public Overloads Sub RemoveService(ByVal serviceType As System.Type, _ ByVal promote As Boolean) Implements IServiceContainer.RemoveService If (localServices(serviceType.FullName) IsNot Nothing) Then localServices.Remove(serviceType.FullName) localServiceTypes.Remove(serviceType.FullName) End If If promote Then If (parentServiceContainer IsNot Nothing) Then parentServiceContainer.RemoveService(serviceType) End If End If End Sub ' IServiceContainer.RemoveService (defaults to promote service removal) Public Overloads Sub RemoveService(ByVal serviceType As System.Type) _ Implements IServiceContainer.RemoveService RemoveService(serviceType, True) End Sub ' Paint method override draws the label string on the control. Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs) e.Graphics.DrawString(label, New Font("Arial", 8), New SolidBrush(Color.Black), 5, 5) End Sub ' Process mouse-down behavior for click. Protected Overrides Sub OnMouseDown(ByVal e As System.Windows.Forms.MouseEventArgs) ' This example control responds to mouse clicks as follows: ' ' Left click - control attempts to obtain a text service ' and sets its label text to the text provided by the service ' Right click - if the control has already provided a text ' service, this control does nothing. Otherwise, the control ' shows a dialog to specify text to provide as a new text ' service, after clearing the tree's services. If e.Button = System.Windows.Forms.MouseButtons.Left Then If state_ <> TextServiceState.ServiceProvided Then ' Attempt to update text from the service, and set ' color state accordingly. Dim ts As TextService = CType(GetService(GetType(TextService)), TextService) If (ts IsNot Nothing) Then Me.label = ts.text state = TextServiceState.ServiceObtained Else Me.label = "Service Not Found" state = TextServiceState.ServiceNotFound End If End If End If If e.Button = System.Windows.Forms.MouseButtons.Right Then If state_ = TextServiceState.ServiceProvided Then ' Remove the service the if the container provided it. If (GetService(GetType(TextService)) IsNot Nothing) Then RemoveService(GetType(TextService), True) state = TextServiceState.ServiceNotObtained Me.label = "Service Removed" End If Else ' Obtain string and provide text service. Using form As New StringInputDialog("Test String") form.StartPosition = FormStartPosition.CenterParent If form.ShowDialog() = DialogResult.OK Then If (GetService(GetType(TextService)) IsNot Nothing) Then RemoveService(GetType(TextService), True) End If parent.ResetServiceTree(Me, New EventArgs()) AddService(GetType(TextService), _ New TextService(form.inputTextBox.Text), True) ' The following commented method uses a service creator callback. ' AddService(typeof(TextService), ' new ServiceCreatorCallback(this.CreateTextService)); state = TextServiceState.ServiceProvided Me.label = "Provided Text: " + form.inputTextBox.Text End If End Using End If End If parent.UpdateServiceCoverage() End Sub ' Method accesses the TextService to test the visibility of the service ' from the control, and sets the UI state accordingly. Public Sub ReflectServiceVisibility() If state_ = TextServiceState.ServiceObtained Then If GetService(GetType(TextService)) Is Nothing Then Me.BackColor = Color.CadetBlue End If ElseIf state_ <> TextServiceState.ServiceProvided Then If GetService(GetType(TextService)) Is Nothing Then Me.BackColor = Color.White Return End If ' Service available. If state_ = TextServiceState.ServiceNotFound Then Me.BackColor = Color.Khaki ElseIf state_ = TextServiceState.ServiceNotObtained _ AndAlso label <> "Service Removed" Then Me.BackColor = Color.Khaki End If End If End Sub ' ServiceCreatorCallback method creates a text service. Private Function CreateTextService(ByVal container As IServiceContainer, _ ByVal serviceType As System.Type) As Object Return New TextService("Test Callback") End Function End Class ' Example form provides UI for demonstrating service sharing behavior ' of a network of IServiceContainer/IServiceProvider controls. Public Class ServiceForm Inherits System.Windows.Forms.Form ' Root service container control for tree. Private root As ServiceContainerControl ' Button for clearing any provided services and resetting tree states. Private WithEvents reset_button As System.Windows.Forms.Button ' Color list used to color code controls. Private colorkeys() As Color Private keystrings() As String ' Strings used to reflect text service Public Sub New() InitializeComponent() colorkeys = New Color() {Color.Beige, Color.SeaShell, _ Color.LightGreen, Color.LightBlue, Color.Khaki, Color.CadetBlue} keystrings = New String() {"No service use", "Service not accessible", _ "Service provided", "Service obtained", "Service accessible", _ "No further access"} CreateServiceControlTree() End Sub Private Sub CreateServiceControlTree() ' Create root service control Dim control1 As New ServiceContainerControl(Nothing, New Size(300, 40), New Point(10, 80), Me) root = control1 ' Create first tier - pass parent with service object control 1. Dim control2 As New ServiceContainerControl(control1, New Size(200, 30), New Point(50, 160), Me) Dim control3 As New ServiceContainerControl(control1, New Size(200, 30), New Point(50, 240), Me) ' Create second tier A - pass parent with service object control 2. Dim control4 As New ServiceContainerControl(control2, New Size(180, 20), New Point(300, 145), Me) Dim control5 As New ServiceContainerControl(control2, New Size(180, 20), New Point(300, 185), Me) ' Create second tier B - pass parent with service object control 3. Dim control6 As New ServiceContainerControl(control3, New Size(180, 20), New Point(300, 225), Me) Dim control7 As New ServiceContainerControl(control3, New Size(180, 20), New Point(300, 265), Me) ' Add controls Me.Controls.AddRange(New Control() {control1, control2, control3, control4, control5, control6, control7}) End Sub Friend Sub ResetServiceTree(ByVal sender As Object, ByVal e As EventArgs) Handles reset_button.Click ' Remove the service from the service tree. If (root.GetService(GetType(TextService)) IsNot Nothing) Then root.RemoveService(GetType(TextService), True) End If ' Set all controls to "not obtained" and clear their labels. Dim i As Integer For i = 0 To Controls.Count - 1 If Not Controls(i).Equals(reset_button) Then CType(Controls(i), ServiceContainerControl).state = TextServiceState.ServiceNotObtained CType(Controls(i), ServiceContainerControl).label = String.Empty CType(Controls(i), ServiceContainerControl).BackColor = Color.Beige End If Next i End Sub Public Sub UpdateServiceCoverage() ' Have each control set state to reflect service availability. Dim i As Integer For i = 0 To Controls.Count - 1 If Not Controls(i).Equals(reset_button) Then CType(Controls(i), ServiceContainerControl).ReflectServiceVisibility() End If Next i End Sub Private Sub InitializeComponent() Me.reset_button = New System.Windows.Forms.Button() Me.SuspendLayout() ' ' reset_button ' Me.reset_button.Location = New System.Drawing.Point(392, 88) Me.reset_button.Name = "reset_button" Me.reset_button.TabIndex = 0 Me.reset_button.TabStop = False Me.reset_button.Text = "Reset" ' ' ServiceForm ' Me.ClientSize = New System.Drawing.Size(512, 373) Me.Controls.AddRange(New System.Windows.Forms.Control() {Me.reset_button}) Me.MinimumSize = New System.Drawing.Size(520, 400) Me.Name = "ServiceForm" Me.Text = "Service Container Architecture Example" Me.ResumeLayout(False) End Sub <STAThread()> _ Shared Sub Main() Application.Run(New ServiceForm()) End Sub Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs) e.Graphics.DrawString("The following tree diagram represents a hierarchy of linked service containers in controls.", New Font("Arial", 9), New SolidBrush(Color.Black), 4, 4) e.Graphics.DrawString("This example demonstrates the propagation behavior of services through a linked service object tree.", New Font("Arial", 8), New SolidBrush(Color.Black), 4, 26) e.Graphics.DrawString("Right-click a component to add or replace a text service, or to remove it if the component provided it.", New Font("Arial", 8), New SolidBrush(Color.Black), 4, 38) e.Graphics.DrawString("Left-click a component to update text from the text service if available.", New Font("Arial", 8), New SolidBrush(Color.Black), 4, 50) ' Draw lines to represent tree branches. e.Graphics.DrawLine(New Pen(New SolidBrush(Color.Black), 1), 20, 125, 20, 258) e.Graphics.DrawLine(New Pen(New SolidBrush(Color.Black), 1), 21, 175, 45, 175) e.Graphics.DrawLine(New Pen(New SolidBrush(Color.Black), 1), 21, 258, 45, 258) e.Graphics.DrawLine(New Pen(New SolidBrush(Color.Black), 1), 255, 175, 285, 175) e.Graphics.DrawLine(New Pen(New SolidBrush(Color.Black), 1), 255, 258, 285, 258) e.Graphics.DrawLine(New Pen(New SolidBrush(Color.Black), 1), 285, 155, 285, 195) e.Graphics.DrawLine(New Pen(New SolidBrush(Color.Black), 1), 285, 238, 285, 278) e.Graphics.DrawLine(New Pen(New SolidBrush(Color.Black), 1), 285, 155, 290, 155) e.Graphics.DrawLine(New Pen(New SolidBrush(Color.Black), 1), 285, 195, 290, 195) e.Graphics.DrawLine(New Pen(New SolidBrush(Color.Black), 1), 285, 238, 290, 238) e.Graphics.DrawLine(New Pen(New SolidBrush(Color.Black), 1), 285, 278, 290, 278) ' Draw color key. e.Graphics.DrawRectangle(New Pen(New SolidBrush(Color.Black), 1), 20, 305, 410, 60) Dim y As Integer = 0 Dim i As Integer For i = 0 To 2 e.Graphics.FillRectangle(New SolidBrush(colorkeys(y)), _ 25 + i * 140, 310, 20, 20) e.Graphics.DrawRectangle(New Pen(New SolidBrush(Color.Black), 1), _ 25 + i * 140, 310, 20, 20) e.Graphics.DrawString(keystrings(y), New Font("Arial", 8), _ New SolidBrush(Color.Black), 50 + i * 140, 315) y += 1 e.Graphics.FillRectangle(New SolidBrush(colorkeys(y)), _ 25 + i * 140, 340, 20, 20) e.Graphics.DrawRectangle(New Pen(New SolidBrush(Color.Black), 1), _ 25 + i * 140, 340, 20, 20) e.Graphics.DrawString(keystrings(y), New Font("Arial", 8), _ New SolidBrush(Color.Black), 50 + i * 140, 345) y += 1 Next i End Sub End Class ' Example service type contains a text string, sufficient to ' demonstrate service sharing. Public Class TextService Public [text] As String Public Sub New() MyClass.New(String.Empty) End Sub Public Sub New(ByVal [text] As String) Me.text = [text] End Sub End Class Public Enum TextServiceState ServiceNotObtained ServiceObtained ServiceProvided ServiceNotFound End Enum ' Example Form for entering a string. Friend Class StringInputDialog Inherits System.Windows.Forms.Form Private ok_button As System.Windows.Forms.Button Private cancel_button As System.Windows.Forms.Button Public inputTextBox As System.Windows.Forms.TextBox Public Sub New(ByVal [text] As String) InitializeComponent() inputTextBox.Text = [text] End Sub Private Sub InitializeComponent() Me.ok_button = New System.Windows.Forms.Button() Me.cancel_button = New System.Windows.Forms.Button() Me.inputTextBox = New System.Windows.Forms.TextBox() Me.SuspendLayout() Me.ok_button.Anchor = System.Windows.Forms.AnchorStyles.Bottom _ Or System.Windows.Forms.AnchorStyles.Right Me.ok_button.Location = New System.Drawing.Point(180, 43) Me.ok_button.Name = "ok_button" Me.ok_button.TabIndex = 1 Me.ok_button.Text = "OK" Me.ok_button.DialogResult = System.Windows.Forms.DialogResult.OK Me.cancel_button.Anchor = System.Windows.Forms.AnchorStyles.Bottom _ Or System.Windows.Forms.AnchorStyles.Right Me.cancel_button.Location = New System.Drawing.Point(260, 43) Me.cancel_button.Name = "cancel_button" Me.cancel_button.TabIndex = 2 Me.cancel_button.Text = "Cancel" Me.cancel_button.DialogResult = System.Windows.Forms.DialogResult.Cancel Me.inputTextBox.Location = New System.Drawing.Point(6, 9) Me.inputTextBox.Name = "inputTextBox" Me.inputTextBox.Size = New System.Drawing.Size(327, 20) Me.inputTextBox.TabIndex = 0 Me.inputTextBox.Text = "" Me.inputTextBox.Anchor = System.Windows.Forms.AnchorStyles.Top _ Or System.Windows.Forms.AnchorStyles.Left Or _ System.Windows.Forms.AnchorStyles.Right Me.ClientSize = New System.Drawing.Size(342, 73) Me.Controls.AddRange(New System.Windows.Forms.Control() _ {Me.inputTextBox, Me.cancel_button, Me.ok_button}) Me.MinimumSize = New System.Drawing.Size(350, 100) Me.Name = "StringInputDialog" Me.Text = "Text Service Provide String Dialog" Me.ResumeLayout(False) End Sub End Class
package ServiceArchitectureExample;
import System.*;
import System.Drawing.*;
import System.Collections.*;
import System.ComponentModel.*;
import System.ComponentModel.Design.*;
import System.Windows.Forms.*;
import System.Windows.Forms.Design.*;
// This sample contains a Form class that is configured to demonstrate
// the behavior of a network of linked service containers.
// Notes regarding this IServiceContainer and IServiceProvider
// implementation:
//
// When implementing the IServiceContainer interface, you may want to
// implement support for a linked service container system
// which enables access to and sharing of services throughout a
// container tree or network.
//
// To effectively share a service, a GetService, AddService or
// RemoveService method must be able to locate a service
// that has been added to a shared service container tree or network.
//
// One simple approach to sharing services, suitable for container networks
// where each container has one parent and the tree has
// one parentless container, is to store services only at the top node
// (the root or grandparent) of a tree.
//
// To store services in the root node of a tree, two types of
// consistencies must be maintained in the implementation:
//
// > The GetService, AddService and RemoveService implementations
// must access the root through some mechanism.
// The ServiceContainerControl's implementations of these
// standard IServiceContainer methods call
// the same method of a parent container, if the container
// has been parented, to route methods to the root.
//
// > The services must be maintained at the root of the tree;
// therefore, any new child's services should be copied to the root.
// ServiceContainerControl provides an example user control implmentation
// of the IServiceContainer interface. This implementation of
// IServiceContainer supports a root-node linked service distribution,
// access. and removal architecture.
public class ServiceContainerControl extends System.Windows.Forms.UserControl
implements IServiceContainer
{
// List of service instances sorted by key of service type's full name.
private SortedList localServices;
// List that contains the Type for each service sorted by each
// service type's full name.
private SortedList localServiceTypes;
// The parent IServiceContainer, or null.
private IServiceContainer parentServiceContainer;
/** @property
*/
public IServiceContainer get_serviceParent()
{
return parentServiceContainer;
} //get_serviceParent
/** @property
*/
public void set_serviceParent(IServiceContainer value)
{
parentServiceContainer = value;
// Move any services to parent.
for (int i = 0; i < localServices.get_Count(); i++) {
parentServiceContainer.AddService(
(Type)(localServiceTypes.GetByIndex(i)),
localServices.GetByIndex(i));
}
localServices.Clear();
localServiceTypes.Clear();
} //set_serviceParent
// The current state of the control reflecting whether it has
// obtained or provided a text service.
private TextServiceState state_;
/** @property
*/
public TextServiceState get_state()
{
return state_;
} //get_state
/** @property
*/
public void set_state(TextServiceState value)
{
if (value.member == TextServiceState.ServiceProvided){
this.set_BackColor(Color.get_LightGreen());
}
else {
if (value.member == TextServiceState.ServiceNotObtained) {
this.set_BackColor(Color.get_White());
}
else {
if (value.member == TextServiceState.ServiceObtained) {
this.set_BackColor(Color.get_LightBlue());
}
else {
if (value.member == TextServiceState.ServiceNotFound) {
this.set_BackColor(Color.get_SeaShell());
}
}
}
}
state_ = value;
} //set_state
// Parent form reference for main program function access.
private ServiceForm parent;
// String for label displayed on the control to indicate
// the control's current service-related configuration state.
public String label;
public ServiceContainerControl(Size size, Point location,
ServiceForm parent)
{
this(null, size, location, parent);
} //ServiceContainerControl
public ServiceContainerControl(IServiceContainer ParentServiceContainer,
Size size, Point location, ServiceForm parent)
{
this.set_state(new TextServiceState(
TextServiceState.ServiceNotObtained));
localServices = new SortedList();
localServiceTypes = new SortedList();
this.set_BackColor(Color.get_Beige());
this.label = "";
this.set_Size(size);
this.set_Location(location);
this.parent = parent;
this.set_serviceParent(ParentServiceContainer);
// If a parent is specified, set the parent property of this
// linkable IServiceContainer implementation.
if (ParentServiceContainer != null) {
set_serviceParent(ParentServiceContainer);
}
} //ServiceContainerControl
// IServiceProvider.GetService implementation for a linked
// service container architecture.
public Object GetService(System.Type serviceType)
{
if (parentServiceContainer != null) {
return parentServiceContainer.GetService(serviceType);
}
Object serviceInstance
= localServices.get_Item(serviceType.get_FullName());
if (serviceInstance == null) {
return null;
}
else {
if (serviceInstance.GetType().
Equals (ServiceCreatorCallback.class.ToType())) {
// If service instance is a ServiceCreatorCallback, invoke
// it to create the service.
return ((ServiceCreatorCallback)serviceInstance).
Invoke(this, serviceType);
}
}
return serviceInstance;
} //GetService
// IServiceContainer.AddService implementation for a linked
// service container architecture.
public void AddService(System.Type serviceType,
System.ComponentModel.Design.ServiceCreatorCallback callback,
boolean promote)
{
if (promote && parentServiceContainer != null) {
parentServiceContainer.AddService(serviceType, callback, true);
}
else {
localServiceTypes.set_Item(serviceType.get_FullName(), serviceType);
localServices.set_Item(serviceType.get_FullName(), callback);
}
} //AddService
// IServiceContainer.AddService implementation for a linked
// service container architecture.
public void AddService(System.Type serviceType,
System.ComponentModel.Design.ServiceCreatorCallback callback)
{
AddService(serviceType, callback, true);
} //AddService
// IServiceContainer.AddService implementation for a linked
// service container architecture.
public void AddService(System.Type serviceType,
Object serviceInstance, boolean promote)
{
if (promote && parentServiceContainer != null) {
parentServiceContainer.AddService(serviceType,
serviceInstance, true);
}
else {
localServiceTypes.set_Item(serviceType.get_FullName(), serviceType);
localServices.set_Item(serviceType.get_FullName(), serviceInstance);
}
} //AddService
// IServiceContainer.AddService (defaults to promote service addition).
public void AddService(System.Type serviceType, Object serviceInstance)
{
AddService(serviceType, serviceInstance, true);
} //AddService
// IServiceContainer.RemoveService implementation for a linked
// service container architecture.
public void RemoveService(System.Type serviceType, boolean promote)
{
if (localServices.get_Item(serviceType.get_FullName()) != null) {
localServices.Remove(serviceType.get_FullName());
localServiceTypes.Remove(serviceType.get_FullName());
}
if (promote) {
if (parentServiceContainer != null) {
parentServiceContainer.RemoveService(serviceType);
}
}
} //RemoveService
// IServiceContainer.RemoveService (defaults to promote
// service removal)
public void RemoveService(System.Type serviceType)
{
RemoveService(serviceType, true);
} //RemoveService
// Paint method override draws the label string on the control.
protected void OnPaint(System.Windows.Forms.PaintEventArgs e)
{
e.get_Graphics().DrawString(label, new Font("Arial", 8),
new SolidBrush(Color.get_Black()), 5, 5);
} //OnPaint
// Process mouse-down behavior for click.
protected void OnMouseDown(System.Windows.Forms.MouseEventArgs e)
{
// This example control responds to mouse clicks as follows:
//
// Left click - control attempts to obtain a text service
// and sets its label text to the text provided by the service
// Right click - if the control has already provided a text
// service, this control does nothing. Otherwise, the control
// shows a dialog box to specify text to provide as a new text
// service, after clearing the tree's services.
if (e.get_Button().Equals (get_MouseButtons().Left)) {
if (!(state_ .Equals (new TextServiceState(
TextServiceState.ServiceProvided)))) {
// Attempt to update text from service, and set
// color state accordingly.
TextService ts
= (TextService)(GetService(TextService.class.ToType()));
if (ts != null) {
this.label = ts.text;
set_state(new TextServiceState(
TextServiceState.ServiceObtained));
}
else {
this.label = "Service Not Found";
set_state(new TextServiceState(
TextServiceState.ServiceNotFound));
}
}
}
if (e.get_Button().Equals (get_MouseButtons().Right)) {
if (state_.Equals (new TextServiceState(
TextServiceState.ServiceProvided))) {
// Remove the service if the container provided it.
if (GetService(TextService.class.ToType()) != null) {
RemoveService(TextService.class.ToType(), true);
set_state(new TextServiceState(
TextServiceState.ServiceNotObtained));
this.label = "Service Removed";
}
}
else {
// Obtain string and provide text service.
StringInputDialog form = new StringInputDialog("Test String");
form.set_StartPosition(FormStartPosition.CenterParent);
if (form.ShowDialog().Equals(DialogResult.OK)) {
if (GetService(TextService.class.ToType()) != null) {
RemoveService(TextService.class.ToType(), true);
}
parent.ResetServiceTree(this, new EventArgs());
AddService(TextService.class.ToType(),
new TextService(form.inputTextBox.get_Text()), true);
// The following commented method uses a
// service creator callback.
// AddService(typeof(TextService),
// new ServiceCreatorCallback(this.CreateTextService));
set_state(
new TextServiceState(TextServiceState.ServiceProvided));
this.label = "Provided Text: "
+ form.inputTextBox.get_Text();
}
}
}
parent.UpdateServiceCoverage();
} //OnMouseDown
// Method accesses the TextService to test the visibility of the
// service from the control, and sets the UI state accordingly.
public void ReflectServiceVisibility()
{
if (state_.Equals(new TextServiceState(
TextServiceState.ServiceObtained))) {
if (GetService(TextService.class.ToType()) == null) {
this.set_BackColor(Color.get_CadetBlue());
}
}
else {
if (!(state_.Equals(new TextServiceState(
TextServiceState.ServiceProvided)))) {
if (GetService(TextService.class.ToType()) == null) {
this.set_BackColor(Color.get_White());
return;
}
// Service available.
if (state_.Equals(new TextServiceState(
TextServiceState.ServiceNotFound))) {
this.set_BackColor(Color.get_Khaki());
}
else {
if (state_.Equals(new TextServiceState(
TextServiceState.ServiceNotObtained))
&& !(label.Equals("Service Removed"))) {
this.set_BackColor(Color.get_Khaki());
}
}
}
}
} //ReflectServiceVisibility
// ServiceCreatorCallback method creates a text service.
private Object CreateTextService(
IServiceContainer container, System.Type serviceType)
{
return new TextService("Test Callback");
} //CreateTextService
} //ServiceContainerControl
// Example form provides UI for demonstrating service sharing behavior
// of a network of IServiceContainer/IServiceProvider controls.
public class ServiceForm extends System.Windows.Forms.Form
{
// Root service container control for tree.
private ServiceContainerControl root;
// Button for clearing any provided services and resetting tree states.
private System.Windows.Forms.Button reset_button;
// Color list used to color code controls.
private Color colorkeys[];
// Strings used to reflect text service.
private String keystrings[];
public ServiceForm()
{
InitializeComponent();
colorkeys = new Color[] { Color.get_Beige(), Color.get_SeaShell(),
Color.get_LightGreen(), Color.get_LightBlue(), Color.get_Khaki(),
Color.get_CadetBlue() };
keystrings = new String[] { "No service use", "Service not accessible",
"Service provided", "Service obtained", "Service accessible",
"No further access" };
CreateServiceControlTree();
} //ServiceForm
private void CreateServiceControlTree()
{
// Create root service control
ServiceContainerControl control1 = new ServiceContainerControl(null,
new Size(300, 40), new Point(10, 80), this);
root = control1;
// Create first tier - pass parent with service object control 1.
ServiceContainerControl control2 = new ServiceContainerControl(control1,
new Size(200, 30), new Point(50, 160), this);
ServiceContainerControl control3 = new ServiceContainerControl(control1,
new Size(200, 30), new Point(50, 240), this);
// Create second tier A - pass parent with service object control 2.
ServiceContainerControl control4 = new ServiceContainerControl(control2,
new Size(180, 20), new Point(300, 145), this);
ServiceContainerControl control5 = new ServiceContainerControl(control2,
new Size(180, 20), new Point(300, 185), this);
// Create second tier B - pass parent with service object control 3.
ServiceContainerControl control6 = new ServiceContainerControl(control3,
new Size(180, 20), new Point(300, 225), this);
ServiceContainerControl control7 = new ServiceContainerControl(control3,
new Size(180, 20), new Point(300, 265), this);
// Add controls
this.get_Controls().AddRange(new Control[] { control1, control2,
control3, control4, control5, control6, control7 });
} //CreateServiceControlTree
public void ResetServiceTree(Object sender, EventArgs e)
{
// Remove the service from the service tree.
if (root.GetService(TextService.class.ToType()) != null) {
root.RemoveService(TextService.class.ToType(), true);
}
// Set all controls to "not obtained" and clear their labels.
for (int i = 0; i < get_Controls().get_Count(); i++) {
if (!(get_Controls().get_Item(i).Equals(reset_button))) {
((ServiceContainerControl)(get_Controls().get_Item(i))).
set_state(new TextServiceState(
TextServiceState.ServiceNotObtained));
((ServiceContainerControl)(
get_Controls().get_Item(i))).label ="" ;
((ServiceContainerControl)(get_Controls().get_Item(i))).
set_BackColor(Color.get_Beige());
}
}
} //ResetServiceTree
public void UpdateServiceCoverage()
{
// Have each control set state to reflect service availability.
for (int i = 0; i < get_Controls().get_Count(); i++) {
if (!(get_Controls().get_Item(i).Equals(reset_button))) {
((ServiceContainerControl)(get_Controls().get_Item(i))).
ReflectServiceVisibility();
}
}
} //UpdateServiceCoverage
private void InitializeComponent()
{
this.reset_button = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// reset_button
//
this.reset_button.set_Location(new System.Drawing.Point(392, 88));
this.reset_button.set_Name("reset_button");
this.reset_button.set_TabIndex(0);
this.reset_button.set_TabStop(false);
this.reset_button.set_Text("Reset");
this.reset_button.add_Click(new System.EventHandler(
this.ResetServiceTree));
//
// ServiceForm
//
this.set_ClientSize(new System.Drawing.Size(512, 373));
this.get_Controls().AddRange(new System.Windows.Forms.Control[]
{ this.reset_button });
this.set_MinimumSize(new System.Drawing.Size(520, 400));
this.set_Name("ServiceForm");
this.set_Text("Service Container Architecture Example");
this.ResumeLayout(false);
} //InitializeComponent
/** @attribute STAThread()
*/
public static void main(String[] args)
{
Application.Run(new ServiceForm());
} //main
protected void OnPaint(System.Windows.Forms.PaintEventArgs e)
{
e.get_Graphics().DrawString("The following tree diagram represents a "
+ "hierarchy of linked service containers in controls.",
new Font("Arial", 9), new SolidBrush(Color.get_Black()), 4, 4);
e.get_Graphics().DrawString("This example demonstrates the propagation "
+ "behavior of services through a linked service object tree.",
new Font("Arial", 8), new SolidBrush(Color.get_Black()), 4, 26);
e.get_Graphics().DrawString("Right-click a component to add or "
+"replace a " + "text service, or to remove it if the component"
+" provided it.", new Font("Arial", 8),
new SolidBrush(Color.get_Black()), 4, 38);
e.get_Graphics().DrawString("Left-click a component to update text from "
+ "the text service if available.", new Font("Arial", 8),
new SolidBrush(Color.get_Black()), 4, 50);
// Draw lines to represent tree branches.
e.get_Graphics().DrawLine(new Pen(new SolidBrush(Color.get_Black()), 1),
20, 125, 20, 258);
e.get_Graphics().DrawLine(new Pen(new SolidBrush(Color.get_Black()), 1),
21, 175, 45, 175);
e.get_Graphics().DrawLine(new Pen(new SolidBrush(Color.get_Black()), 1),
21, 258, 45, 258);
e.get_Graphics().DrawLine(new Pen(new SolidBrush(Color.get_Black()), 1),
255, 175, 285, 175);
e.get_Graphics().DrawLine(new Pen(new SolidBrush(Color.get_Black()), 1),
255, 258, 285, 258);
e.get_Graphics().DrawLine(new Pen(new SolidBrush(Color.get_Black()), 1),
285, 155, 285, 195);
e.get_Graphics().DrawLine(new Pen(new SolidBrush(Color.get_Black()), 1),
285, 238, 285, 278);
e.get_Graphics().DrawLine(new Pen(new SolidBrush(Color.get_Black()), 1),
285, 155, 290, 155);
e.get_Graphics().DrawLine(new Pen(new SolidBrush(Color.get_Black()), 1),
285, 195, 290, 195);
e.get_Graphics().DrawLine(new Pen(new SolidBrush(Color.get_Black()), 1),
285, 238, 290, 238);
e.get_Graphics().DrawLine(new Pen(new SolidBrush(Color.get_Black()), 1),
285, 278, 290, 278);
// Draw color key.
e.get_Graphics().DrawRectangle(new Pen(new SolidBrush(Color.get_Black()),
1), 20, 305, 410, 60);
int y = 0;
for (int i = 0; i < 3; i++) {
e.get_Graphics().FillRectangle(new SolidBrush(colorkeys[y]),
25 + i * 140, 310, 20, 20);
e.get_Graphics().DrawRectangle(new Pen(new SolidBrush(
Color.get_Black()), 1), 25 + i * 140, 310, 20, 20);
e.get_Graphics().DrawString(keystrings[y], new Font("Arial", 8),
new SolidBrush(Color.get_Black()), 50 + i * 140, 315);
y++;
e.get_Graphics().FillRectangle(new SolidBrush(colorkeys[y]),
25 + i * 140, 340, 20, 20);
e.get_Graphics().DrawRectangle(new Pen(new SolidBrush(Color.get_Black()),
1), 25 + i * 140, 340, 20, 20);
e.get_Graphics().DrawString(keystrings[y], new Font("Arial", 8),
new SolidBrush(Color.get_Black()), (50 + i * 140), 345);
y++;
}
} //OnPaint
} //ServiceForm
// Example service type contains a text string, sufficient to
// demonstrate service sharing.
public class TextService
{
public String text;
public TextService()
{
this("");
} //TextService
public TextService(String text)
{
this.text = text;
} //TextService
} //TextService
public class TextServiceState
{
public int member;
TextServiceState()
{
member = 1;
}
TextServiceState(int n)
{
member = n;
}
public static int ServiceNotObtained = 1;
public static int ServiceObtained = 2;
public static int ServiceProvided = 3;
public static int ServiceNotFound = 4;
} //TextServiceState
// Example Form for entering a string.
class StringInputDialog extends System.Windows.Forms.Form
{
private System.Windows.Forms.Button ok_button;
private System.Windows.Forms.Button cancel_button;
public System.Windows.Forms.TextBox inputTextBox;
public StringInputDialog(String text)
{
InitializeComponent();
inputTextBox.set_Text(text);
} //StringInputDialog
private void InitializeComponent()
{
this.ok_button = new System.Windows.Forms.Button();
this.cancel_button = new System.Windows.Forms.Button();
this.inputTextBox = new System.Windows.Forms.TextBox();
this.SuspendLayout();
this.ok_button.set_Anchor(System.Windows.Forms.AnchorStyles.Bottom
| System.Windows.Forms.AnchorStyles.Right);
this.ok_button.set_Location(new System.Drawing.Point(180, 43));
this.ok_button.set_Name("ok_button");
this.ok_button.set_TabIndex(1);
this.ok_button.set_Text("OK");
this.ok_button.set_DialogResult(System.Windows.Forms.DialogResult.OK);
this.cancel_button.set_Anchor(System.Windows.Forms.AnchorStyles.Bottom
| System.Windows.Forms.AnchorStyles.Right);
this.cancel_button.set_Location(new System.Drawing.Point(260, 43));
this.cancel_button.set_Name("cancel_button");
this.cancel_button.set_TabIndex(2);
this.cancel_button.set_Text("Cancel");
this.cancel_button.set_DialogResult(
System.Windows.Forms.DialogResult.Cancel);
this.inputTextBox.set_Location(new System.Drawing.Point(6, 9));
this.inputTextBox.set_Name("inputTextBox");
this.inputTextBox.set_Size(new System.Drawing.Size(327, 20));
this.inputTextBox.set_TabIndex(0);
this.inputTextBox.set_Text("");
this.inputTextBox.set_Anchor(System.Windows.Forms.AnchorStyles.Top
| System.Windows.Forms.AnchorStyles.Left
| System.Windows.Forms.AnchorStyles.Right);
this.set_ClientSize(new System.Drawing.Size(342, 73));
this.get_Controls().AddRange(new System.Windows.Forms.Control[]
{ this.inputTextBox, this.cancel_button, this.ok_button });
this.set_MinimumSize(new System.Drawing.Size(350, 100));
this.set_Name("StringInputDialog");
this.set_Text("Text Service Provide String Dialog");
this.ResumeLayout(false);
} //InitializeComponent
} //StringInputDialog
Windows 98, Windows Server 2000 SP4, Windows Millennium Edition, Windows Server 2003, Windows XP Media Center Edition, Windows XP Professional x64 Edition, Windows XP SP2, Windows XP Starter Edition
The Microsoft .NET Framework 3.0 is supported on Windows Vista, Microsoft Windows XP SP2, and Windows Server 2003 SP1.