Actually, according to the requirements introduced a moment
ago, we can naturally conceive a very simple while practical solution. We can
define a ServiceManager class which will be responsible for maintaining the
common manipulations of the service objects (start or stop). Listing 2
indicates the definition for class ServiceManager.
Listing 2: The definition for class ServiceManager
public class ServiceManager
{
private List<ServiceObject> m_serviceList = new List<ServiceObject>();
static ServiceManager()
{
Initialize();
}
public List<ServiceObject> ServiceList
{
get { return m_serviceList; }
}
private static void Initialize()
{
//omit the concrete implementation...
//initializing the service objects and
//add them into variable m_serviceList
}
public static void StartService(ServiceObject obj)
{
if (obj.CurrentState.Equals(ServiceState.Stop))
{
Switch (obj.ActiveMode)
{
case ActiveMode.Singleton:
RemotingConfiguration.RegisterWellKnownServiceType(
obj.ObjectType,obj.ServiceName,
WellKnownObjectMode.Singleton);
obj.CurrentState=ServiceState.Start;
break;
case ActiveMode.SingleCall:
RemotingConfiguration.RegisterWellKnownServiceType(
obj.ObjectType,obj.ServiceName,
WellKnownObjectMode.SingleCall);
obj.CurrentState=ServiceState.Start;
break;
case ActiveMode.Activation:
RemotingServices.Marshal(
(MarshalByRefObject)obj.ServiceInstance,
obj.ServiceName);
obj.CurrentState=ServiceState.Start;
break;
}
}
}
public static void StopService(ServiceObject obj)
{
if (obj.CurrentState.Equals(ServiceState.Start))
{
Switch (obj.ActiveMode)
{
case ActiveMode.Singleton:
//no implementation
break;
case ActiveMode.SingleCall:
//no implementation
break;
case ActiveMode.Activation:
RemotingServices.Disconnect
(MarshalByRefObject)obj.ServiceInstance);
obj.CurrentState=ServiceState.Stop;
break;
}
}
}
}
Herein, the Initialize method is used to initialize the
service object. Concretely, it takes the responsibility of reading out information
about the service object from inside the configure file, establishing the
service object, and then adding it into the m_seviceList object.
In addition to what is listed above, SeviceManager has to
provide methods to start/stop all the service objects. Because the stop related
methods are similar to start, we are still to abridge the stop service related
code while only give the start related ones below.
Listing 3
public static void StartAllServices()
{
foreach (ServiceObject obj in m_serviceList)
{
StartService(obj);
}
}
public static void StartAllServices(ActiveMode activeMode)
{
foreach (ServiceObject obj in m_serviceList)
{
if (obj.ActiveMode.Equals(activeMode))
{
StartService(obj);
}
}
}
Because the shortcut menu PopupMenu is associated with the ListView
control, we can obtain the service object information through the
currently-selected item on the ListView control when right-clicking the
ListView control. For example, the Name of the service can be obtained through the
following code.
Listing 4
String serviceName=lvService.SelectedItems[0].
SubItems[0].Text;
In the ServiceManager definition, method StartService and
StopService receivesthe object of the ServiceObject type. To invoke these
methods only knowing of the service name is not enough, and we have to also
provide the ServiceObject object. Therefore, we still need to define another
method-- LookUpServiceObject, which seeks the related ServiceObject object in
the m_serviceList object according to the given argument ServiceName.
Listing 5
protected static ServiceObject LookUpServiceObject(string serviceName)
{
foreach (ServiceObject obj in m_serviceList)
{
if (obj.ServiceName.Equals(serviceName))
{
return obj;
}
}
return null;
}
The menu item "Start--Start By Service Name" in
the shortcut menu related Click event handler can be implemented below:
Listing 6
private void startByServiceNameToolStripMenuItem_Click(object sender, EventArgs e)
{
string serviceName = lvService.SelectedItems[0].SubItems[0].Text;
ServiceObject obj=ServiceManager.LookUpServiceObject(serviceName);
if(obj!=null)
{
ServiceManager.StartService(obj);
}
}
As for the click handler for the
menu item "Start All", it is much simpler, as follows.
private void munStartAll_Click(object sender, EventArgs e)
{
ServiceManager.StartAllServices();
}
For now, we have nearly accomplished the design of the
service explorer application. Surveying the whole design, it is simple yet
practical, which can meet the requirements brought out at the beginning. In the
above programming, we have used OOP as much as possible. Although the design of
class ServiceManager is not very elegant, while from the angle of availability,
such a design is enough.
By digging deeper, we find out that the above design can
still be improved, which can be done by introducing the Template Method
pattern.