120 lines
4.4 KiB
C#
120 lines
4.4 KiB
C#
|
using System;
|
|||
|
using System.Reflection;
|
|||
|
using ln.logging;
|
|||
|
using System.IO;
|
|||
|
using System.Linq;
|
|||
|
namespace ln.application.service
|
|||
|
{
|
|||
|
public class ServiceDefinition
|
|||
|
{
|
|||
|
public String AssemblyName { get; }
|
|||
|
public String ServiceClassName { get; }
|
|||
|
public bool AutoStart { get; set; }
|
|||
|
|
|||
|
public ApplicationServiceBase ServiceBase { get; private set; }
|
|||
|
|
|||
|
public bool IsLoaded => ServiceBase != null;
|
|||
|
public bool IsAlive => IsLoaded && ServiceBase.IsAlive;
|
|||
|
|
|||
|
Assembly serviceAssembly;
|
|||
|
Type serviceType;
|
|||
|
|
|||
|
public ServiceDefinition(String assemblyName, string serviceClassName)
|
|||
|
{
|
|||
|
AssemblyName = assemblyName;
|
|||
|
ServiceClassName = serviceClassName;
|
|||
|
}
|
|||
|
public ServiceDefinition(string serviceClassName)
|
|||
|
{
|
|||
|
AssemblyName = null;
|
|||
|
ServiceClassName = serviceClassName;
|
|||
|
}
|
|||
|
public static ServiceDefinition From<S>() => From<S>(true);
|
|||
|
public static ServiceDefinition From<S>(bool autoStart)
|
|||
|
{
|
|||
|
Type st = typeof(S);
|
|||
|
ServiceDefinition sd = new ServiceDefinition(
|
|||
|
st.Assembly.FullName,
|
|||
|
st.FullName
|
|||
|
);
|
|||
|
sd.AutoStart = autoStart;
|
|||
|
return sd;
|
|||
|
}
|
|||
|
|
|||
|
public void Load()
|
|||
|
{
|
|||
|
if (IsLoaded)
|
|||
|
throw new NotSupportedException(String.Format("Service {0} [{1}] is already loaded",ServiceClassName,AssemblyName));
|
|||
|
|
|||
|
if (AssemblyName != null)
|
|||
|
serviceAssembly = Assembly.Load(AssemblyName);
|
|||
|
|
|||
|
serviceType = FinalAssembly.GetType(ServiceClassName);
|
|||
|
if (serviceType == null)
|
|||
|
throw new EntryPointNotFoundException(String.Format("could not get type {0}",ServiceClassName));
|
|||
|
|
|||
|
if (!serviceType.IsSubclassOf(typeof(ApplicationServiceBase)))
|
|||
|
throw new NotSupportedException(String.Format("application service type must derive from ApplicationServiceBase"));
|
|||
|
|
|||
|
ServiceBase = (ApplicationServiceBase)Activator.CreateInstance(serviceType);
|
|||
|
}
|
|||
|
public void Unload() => Unload(false);
|
|||
|
public void Unload(bool force)
|
|||
|
{
|
|||
|
if (!IsLoaded)
|
|||
|
throw new NotSupportedException(String.Format("Service {0} [{1}] is not loaded", ServiceClassName, AssemblyName));
|
|||
|
|
|||
|
if (!force && IsAlive)
|
|||
|
throw new NotSupportedException(String.Format("Service {0} [{1}] still alive", ServiceClassName, AssemblyName));
|
|||
|
|
|||
|
ServiceBase.Dispose();
|
|||
|
|
|||
|
ServiceBase = null;
|
|||
|
serviceType = null;
|
|||
|
serviceAssembly = null;
|
|||
|
}
|
|||
|
public void Start(IApplicationInterface applicationInterface)
|
|||
|
{
|
|||
|
if (!IsLoaded)
|
|||
|
Load();
|
|||
|
|
|||
|
Logging.Log(LogLevel.INFO, "service: starting {0} [{1}]", ServiceClassName, FinalAssembly.GetName().Name);
|
|||
|
|
|||
|
if (ServiceBase.Start(applicationInterface,new string[0]))
|
|||
|
Logging.Log(LogLevel.INFO, "service: started {0} [{1}]", ServiceClassName, FinalAssembly.GetName().Name);
|
|||
|
else
|
|||
|
Logging.Log(LogLevel.ERROR, "service: failed {0} [{1}]", ServiceClassName, FinalAssembly.GetName().Name);
|
|||
|
}
|
|||
|
public void Stop()
|
|||
|
{
|
|||
|
if (IsAlive)
|
|||
|
{
|
|||
|
Logging.Log(LogLevel.INFO, "service: stopping {0} [{1}]", ServiceClassName, FinalAssembly.GetName().Name);
|
|||
|
|
|||
|
if (ServiceBase.Stop())
|
|||
|
Logging.Log(LogLevel.INFO, "service: stopped {0} [{1}]", ServiceClassName, FinalAssembly.GetName().Name);
|
|||
|
else
|
|||
|
Logging.Log(LogLevel.ERROR, "service: stopfail {0} [{1}]", ServiceClassName, FinalAssembly.GetName().Name);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private Assembly FinalAssembly => serviceAssembly != null ? serviceAssembly : Assembly.GetEntryAssembly();
|
|||
|
|
|||
|
public override int GetHashCode()
|
|||
|
{
|
|||
|
return (AssemblyName != null ? AssemblyName.GetHashCode() : 0) ^ ServiceClassName.GetHashCode();
|
|||
|
}
|
|||
|
public override bool Equals(object obj)
|
|||
|
{
|
|||
|
if (obj is ServiceDefinition)
|
|||
|
{
|
|||
|
ServiceDefinition other = obj as ServiceDefinition;
|
|||
|
return Object.Equals(AssemblyName, other.AssemblyName) && ServiceClassName.Equals(other.ServiceClassName);
|
|||
|
}
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
}
|
|||
|
}
|