ln.application/service/ServiceContainer.cs

168 lines
5.6 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using ln.logging;
namespace ln.application.service
{
public class ServiceContainer : IEnumerable<ServiceDefinition>
{
public Application Application { get; }
public ServiceContainerRPC RPC
{
get
{
if (rpc == null)
rpc = new ServiceContainerRPC(this);
return rpc;
}
}
ServiceContainerRPC rpc;
HashSet<ServiceDefinition> serviceDefinitions = new HashSet<ServiceDefinition>();
public ServiceContainer(Application application)
{
Application = application;
}
public void Add(ServiceDefinition serviceDefinition)
{
serviceDefinitions.Add(serviceDefinition);
}
public void Remove(ServiceDefinition serviceDefinition)
{
serviceDefinitions.Remove(serviceDefinition);
}
public ServiceDefinition this[string serviceClassName]
{
get
{
foreach (ServiceDefinition serviceDefinition in serviceDefinitions)
{
if (serviceDefinition.ServiceClassName.Equals(serviceClassName))
return serviceDefinition;
}
throw new KeyNotFoundException();
}
}
public ServiceDefinition this[string assemblyName,string serviceClassName]
{
get
{
foreach (ServiceDefinition serviceDefinition in serviceDefinitions)
{
if (serviceDefinition.ServiceClassName.Equals(serviceClassName) && Object.Equals(serviceDefinition.AssemblyName,assemblyName))
return serviceDefinition;
}
throw new KeyNotFoundException();
}
}
public ServiceDefinition this[Type serviceType]
{
get
{
return this[serviceType.Assembly.FullName,serviceType.FullName];
}
}
public void Start(ServiceDefinition serviceDefinition)
{
if (!serviceDefinitions.Contains(serviceDefinition))
throw new NotSupportedException("ServiceDefinition not known to ServiceContainer");
ServiceDefinition sd = this[serviceDefinition.AssemblyName, serviceDefinition.ServiceClassName];
sd.Start(this.Application);
}
public void Stop(ServiceDefinition serviceDefinition)
{
if (!serviceDefinitions.Contains(serviceDefinition))
throw new NotSupportedException("ServiceDefinition not known to ServiceContainer");
ServiceDefinition sd = this[serviceDefinition.AssemblyName, serviceDefinition.ServiceClassName];
foreach (ServiceDefinition service in serviceDefinitions)
{
if (service.IsAlive)
{
if (service.ServiceBase.DependingServiceTypes.Contains(sd.ServiceType))
{
Logging.Log(LogLevel.INFO, "Stopping depending Service: {0}", service.ServiceClassName);
Stop(service);
}
}
}
sd.Stop();
}
public void Load(ServiceDefinition serviceDefinition)
{
if (!serviceDefinitions.Contains(serviceDefinition))
throw new NotSupportedException("ServiceDefinition not known to ServiceContainer");
ServiceDefinition sd = this[serviceDefinition.AssemblyName, serviceDefinition.ServiceClassName];
sd.Load();
}
public void Unload(ServiceDefinition serviceDefinition)
{
if (!serviceDefinitions.Contains(serviceDefinition))
throw new NotSupportedException("ServiceDefinition not known to ServiceContainer");
ServiceDefinition sd = this[serviceDefinition.AssemblyName, serviceDefinition.ServiceClassName];
sd.Unload();
}
public IEnumerator<ServiceDefinition> GetEnumerator()
{
return ((IEnumerable<ServiceDefinition>)serviceDefinitions).GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable<ServiceDefinition>)serviceDefinitions).GetEnumerator();
}
public class ServiceContainerRPC
{
public ServiceContainer ServiceContainer { get; }
public ServiceContainerRPC(ServiceContainer serviceContainer)
{
ServiceContainer = serviceContainer;
}
public String[] GetServiceNames()
{
return ServiceContainer.Select((x) => x.ServiceClassName).ToArray();
}
public sServiceDefinition GetServiceDefinition(string serviceClass)
{
return new sServiceDefinition(ServiceContainer[serviceClass]);
}
}
public struct sServiceDefinition
{
public String ServiceClassName;
public bool IsLoaded;
public bool IsAlive;
public bool IsReady;
public sServiceDefinition(ServiceDefinition serviceDefinition)
{
ServiceClassName = serviceDefinition.ServiceClassName;
IsLoaded = serviceDefinition.IsLoaded;
IsAlive = serviceDefinition.IsAlive;
IsReady = serviceDefinition.ServiceBase != null ? serviceDefinition.ServiceBase.IsReady : false;
}
}
}
}