Refactored naming and directory layout of project.
This commit is contained in:
		
							
								
								
									
										4
									
								
								.vscode/launch.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.vscode/launch.json
									
									
									
									
										vendored
									
									
								
							@@ -10,9 +10,9 @@
 | 
			
		||||
            "request": "launch",
 | 
			
		||||
            "preLaunchTask": "build",
 | 
			
		||||
            // If you have changed target frameworks, make sure to update the program path.
 | 
			
		||||
            "program": "${workspaceFolder}/src/GameServiceWarden.Host/bin/Debug/netcoreapp3.1/GameServiceWarden.Host.dll",
 | 
			
		||||
            "program": "${workspaceFolder}/src/GameServiceWarden.Core/bin/Debug/netcoreapp3.1/GameServiceWarden.Core.dll",
 | 
			
		||||
            "args": [],
 | 
			
		||||
            "cwd": "${workspaceFolder}/src/GameServiceWarden.Host",
 | 
			
		||||
            "cwd": "${workspaceFolder}/src/GameServiceWarden.Core",
 | 
			
		||||
            // For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console
 | 
			
		||||
            "console": "internalConsole",
 | 
			
		||||
            "stopAtEntry": false
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										6
									
								
								.vscode/tasks.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								.vscode/tasks.json
									
									
									
									
										vendored
									
									
								
							@@ -7,7 +7,7 @@
 | 
			
		||||
            "type": "process",
 | 
			
		||||
            "args": [
 | 
			
		||||
                "build",
 | 
			
		||||
                "${workspaceFolder}/src/GameServiceWarden.Host/GameServiceWarden.Host.csproj",
 | 
			
		||||
                "${workspaceFolder}/src/GameServiceWarden.Core/GameServiceWarden.Core.csproj",
 | 
			
		||||
                "/property:GenerateFullPaths=true",
 | 
			
		||||
                "/consoleloggerparameters:NoSummary"
 | 
			
		||||
            ],
 | 
			
		||||
@@ -19,7 +19,7 @@
 | 
			
		||||
            "type": "process",
 | 
			
		||||
            "args": [
 | 
			
		||||
                "publish",
 | 
			
		||||
                "${workspaceFolder}/src/GameServiceWarden.Host/GameServiceWarden.Host.csproj",
 | 
			
		||||
                "${workspaceFolder}/src/GameServiceWarden.Core/GameServiceWarden.Core.csproj",
 | 
			
		||||
                "/property:GenerateFullPaths=true",
 | 
			
		||||
                "/consoleloggerparameters:NoSummary"
 | 
			
		||||
            ],
 | 
			
		||||
@@ -32,7 +32,7 @@
 | 
			
		||||
            "args": [
 | 
			
		||||
                "watch",
 | 
			
		||||
                "run",
 | 
			
		||||
                "${workspaceFolder}/src/GameServiceWarden.Host/GameServiceWarden.Host.csproj",
 | 
			
		||||
                "${workspaceFolder}/src/GameServiceWarden.Core/GameServiceWarden.Core.csproj",
 | 
			
		||||
                "/property:GenerateFullPaths=true",
 | 
			
		||||
                "/consoleloggerparameters:NoSummary"
 | 
			
		||||
            ],
 | 
			
		||||
 
 | 
			
		||||
@@ -1,10 +1,10 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using GameServiceWarden.Host.Modules.Exceptions;
 | 
			
		||||
 | 
			
		||||
namespace GameServiceWarden.Host.Modules
 | 
			
		||||
namespace GameServiceWarden.Core.Games
 | 
			
		||||
{
 | 
			
		||||
    public class ServiceGateway
 | 
			
		||||
    public class GameServiceGateway
 | 
			
		||||
    {
 | 
			
		||||
        private readonly string dataDirectory;
 | 
			
		||||
        private const string SERVICE_NAME = "Service Name";
 | 
			
		||||
@@ -12,7 +12,7 @@ namespace GameServiceWarden.Host.Modules
 | 
			
		||||
        private const string MODULE_NAME = "Module Name";
 | 
			
		||||
        private const string EXTENSION = ".sin"; //Service info
 | 
			
		||||
 | 
			
		||||
        public ServiceGateway(string dataDirectory)
 | 
			
		||||
        public GameServiceGateway(string dataDirectory)
 | 
			
		||||
        {
 | 
			
		||||
            if (!Directory.Exists(dataDirectory)) Directory.CreateDirectory(dataDirectory);
 | 
			
		||||
            this.dataDirectory = dataDirectory;
 | 
			
		||||
@@ -53,7 +53,8 @@ namespace GameServiceWarden.Host.Modules
 | 
			
		||||
                    return line.Substring(key.Length + 2);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            throw new CorruptedServiceInfoException($"\"{path}\" is corrupted. Could not find value for: {key}.");
 | 
			
		||||
            
 | 
			
		||||
            throw new FormatException($"\"{path}\" is corrupted. Could not find value for: {key}.");
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -4,12 +4,12 @@ using System.Collections.ObjectModel;
 | 
			
		||||
using System.Globalization;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using System.Threading;
 | 
			
		||||
using GameServiceWarden.Host.Preferences;
 | 
			
		||||
using GameServiceWarden.Core.Preferences;
 | 
			
		||||
using GameServiceWarden.ModuleAPI;
 | 
			
		||||
 | 
			
		||||
namespace GameServiceWarden.Host.Modules
 | 
			
		||||
namespace GameServiceWarden.Core.Games
 | 
			
		||||
{
 | 
			
		||||
    public class ServiceInfo : IDisposable //entity
 | 
			
		||||
    public class GameServiceInfo : IDisposable //entity
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
@@ -27,22 +27,22 @@ namespace GameServiceWarden.Host.Modules
 | 
			
		||||
        private readonly IGameService service;
 | 
			
		||||
        private readonly string assemblyName;
 | 
			
		||||
        private readonly string moduleName;
 | 
			
		||||
        private readonly IReadOnlyDictionary<string, IConfigurable> configurables;
 | 
			
		||||
        private readonly IReadOnlyDictionary<string, IGameConfigurable> configurables;
 | 
			
		||||
        private bool disposed;
 | 
			
		||||
 | 
			
		||||
        public ServiceInfo(IGameService service, string moduleName, string assemblyName)
 | 
			
		||||
        public GameServiceInfo(IGameService service, string moduleName, string assemblyName)
 | 
			
		||||
        {
 | 
			
		||||
            this.service = service ?? throw new ArgumentNullException("service");
 | 
			
		||||
            this.moduleName = moduleName ?? throw new ArgumentNullException("moduleName");
 | 
			
		||||
            this.assemblyName = assemblyName ?? throw new ArgumentNullException("assemblyName");
 | 
			
		||||
            this.service.StateChangeEvent += OnServiceStateChange;
 | 
			
		||||
 | 
			
		||||
            Dictionary<string, IConfigurable> configurables = new Dictionary<string, IConfigurable>();
 | 
			
		||||
            foreach (IConfigurable configurable in service.Configurables)
 | 
			
		||||
            Dictionary<string, IGameConfigurable> configurables = new Dictionary<string, IGameConfigurable>();
 | 
			
		||||
            foreach (IGameConfigurable configurable in service.Configurables)
 | 
			
		||||
            {
 | 
			
		||||
                configurables.Add(configurable.OptionName, configurable);
 | 
			
		||||
            }
 | 
			
		||||
            this.configurables = new ReadOnlyDictionary<string, IConfigurable>(configurables);
 | 
			
		||||
            this.configurables = new ReadOnlyDictionary<string, IGameConfigurable>(configurables);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
@@ -93,7 +93,7 @@ namespace GameServiceWarden.Host.Modules
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the possible <see cref="IConfigurable"/>'s names for this service.
 | 
			
		||||
        /// Gets the possible <see cref="IGameConfigurable"/>'s names for this service.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <returns>A <see cref="ISet{string}"/> returned where the string is the option's name.</returns>
 | 
			
		||||
        public ISet<string> GetConfigurableOptions()
 | 
			
		||||
@@ -3,11 +3,11 @@ using System.Collections.Generic;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using GameServiceWarden.ModuleAPI;
 | 
			
		||||
 | 
			
		||||
namespace GameServiceWarden.Host.Modules
 | 
			
		||||
namespace GameServiceWarden.Core.Games
 | 
			
		||||
{
 | 
			
		||||
    public class ServiceManager
 | 
			
		||||
    public class GameServiceManager
 | 
			
		||||
    {
 | 
			
		||||
        private readonly Dictionary<string, ServiceInfo> services = new Dictionary<string, ServiceInfo>();
 | 
			
		||||
        private readonly Dictionary<string, GameServiceInfo> services = new Dictionary<string, GameServiceInfo>();
 | 
			
		||||
        private readonly Dictionary<string, Dictionary<string, IGameServiceModule>> modules = new Dictionary<string, Dictionary<string, IGameServiceModule>>();
 | 
			
		||||
 | 
			
		||||
        public void AddModule(string assemblyName, IGameServiceModule module)
 | 
			
		||||
@@ -44,7 +44,7 @@ namespace GameServiceWarden.Host.Modules
 | 
			
		||||
            if (!modules.ContainsKey(assemblyName) || !modules[assemblyName].ContainsKey(moduleName)) throw new KeyNotFoundException($"No module registered from \"{assemblyName}\" named \"{moduleName}\".");
 | 
			
		||||
            if (services.ContainsKey(serviceName)) throw new ArgumentException($"Service of Name \"{serviceName}\" already exists.");
 | 
			
		||||
 | 
			
		||||
            services.Add(serviceName, new ServiceInfo(modules[assemblyName][moduleName].CreateGameService(), moduleName, assemblyName));
 | 
			
		||||
            services.Add(serviceName, new GameServiceInfo(modules[assemblyName][moduleName].CreateGameService(), moduleName, assemblyName));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void DeleteService(string serviceName)
 | 
			
		||||
@@ -64,7 +64,7 @@ namespace GameServiceWarden.Host.Modules
 | 
			
		||||
        public IEnumerable<string> GetServiceOptions(string serviceName)
 | 
			
		||||
        {
 | 
			
		||||
            if (!services.ContainsKey(serviceName)) throw new KeyNotFoundException($"Service under name \"{serviceName}\" not found.");
 | 
			
		||||
            ServiceInfo serviceInfo = services[serviceName];
 | 
			
		||||
            GameServiceInfo serviceInfo = services[serviceName];
 | 
			
		||||
            return serviceInfo.GetConfigurableOptions();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -0,0 +1,16 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Runtime.Serialization;
 | 
			
		||||
 | 
			
		||||
namespace GameServiceWarden.Core.Games.Modules.Exceptions
 | 
			
		||||
{
 | 
			
		||||
    [System.Serializable]
 | 
			
		||||
    public class ModuleLoadException : Exception
 | 
			
		||||
    {
 | 
			
		||||
        public ModuleLoadException() { }
 | 
			
		||||
        public ModuleLoadException(string message) : base(message) { }
 | 
			
		||||
        public ModuleLoadException(string message, Exception inner) : base(message, inner) { }
 | 
			
		||||
        protected ModuleLoadException(
 | 
			
		||||
            SerializationInfo info,
 | 
			
		||||
            StreamingContext context) : base(info, context) { }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -2,13 +2,13 @@ using System;
 | 
			
		||||
using System.Reflection;
 | 
			
		||||
using System.Runtime.Loader;
 | 
			
		||||
 | 
			
		||||
namespace GameServiceWarden.Host.Modules
 | 
			
		||||
namespace GameServiceWarden.Core.Games.Modules
 | 
			
		||||
{
 | 
			
		||||
    class ModuleLoadContext : AssemblyLoadContext
 | 
			
		||||
    class GameModuleLoadContext : AssemblyLoadContext
 | 
			
		||||
    {
 | 
			
		||||
        private readonly AssemblyDependencyResolver dependencyResolver;
 | 
			
		||||
 | 
			
		||||
        public ModuleLoadContext(string path) {
 | 
			
		||||
        public GameModuleLoadContext(string path) {
 | 
			
		||||
            dependencyResolver = new AssemblyDependencyResolver(path);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -1,12 +1,12 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Reflection;
 | 
			
		||||
using GameServiceWarden.Host.Modules.Exceptions;
 | 
			
		||||
using GameServiceWarden.Core.Games.Modules.Exceptions;
 | 
			
		||||
using GameServiceWarden.ModuleAPI;
 | 
			
		||||
 | 
			
		||||
namespace GameServiceWarden.Host.Modules
 | 
			
		||||
namespace GameServiceWarden.Core.Games.Modules
 | 
			
		||||
{
 | 
			
		||||
    public class ModuleLoader //Gateway
 | 
			
		||||
    public class GameModuleLoader //Gateway
 | 
			
		||||
    {
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Loads an extension module.
 | 
			
		||||
@@ -36,7 +36,7 @@ namespace GameServiceWarden.Host.Modules
 | 
			
		||||
 | 
			
		||||
        private Assembly loadAssembly(string path)
 | 
			
		||||
        {
 | 
			
		||||
            ModuleLoadContext moduleLoadContext = new ModuleLoadContext(path);
 | 
			
		||||
            GameModuleLoadContext moduleLoadContext = new GameModuleLoadContext(path);
 | 
			
		||||
            return moduleLoadContext.LoadFromAssemblyPath(path);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -65,7 +65,7 @@ namespace GameServiceWarden.Host.Modules
 | 
			
		||||
                }
 | 
			
		||||
                string types = String.Join(',', typeNames);
 | 
			
		||||
 | 
			
		||||
                throw new NoServiceableFoundException(
 | 
			
		||||
                throw new ModuleLoadException(
 | 
			
		||||
                    $"No public classes in {assembly} from {assembly.Location} implemented {typeof(IGameService).FullName}." +
 | 
			
		||||
                    $"Detected types: {types}");
 | 
			
		||||
            }
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
using System;
 | 
			
		||||
 | 
			
		||||
namespace GameServiceWarden.Host.Logging
 | 
			
		||||
namespace GameServiceWarden.Core.Logging
 | 
			
		||||
{
 | 
			
		||||
    public class FileLogReceiver : ILogReceiver
 | 
			
		||||
    {
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
using System;
 | 
			
		||||
 | 
			
		||||
namespace GameServiceWarden.Host.Logging
 | 
			
		||||
namespace GameServiceWarden.Core.Logging
 | 
			
		||||
{
 | 
			
		||||
    public interface ILogReceiver
 | 
			
		||||
    {
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
namespace GameServiceWarden.Host.Logging
 | 
			
		||||
namespace GameServiceWarden.Core.Logging
 | 
			
		||||
{
 | 
			
		||||
    public enum LogLevel
 | 
			
		||||
    {
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
 | 
			
		||||
namespace GameServiceWarden.Host.Logging
 | 
			
		||||
namespace GameServiceWarden.Core.Logging
 | 
			
		||||
{
 | 
			
		||||
    public class Logger {
 | 
			
		||||
        private readonly HashSet<ILogReceiver> listeners = new HashSet<ILogReceiver>();
 | 
			
		||||
@@ -4,7 +4,7 @@ using System.Net;
 | 
			
		||||
using System.Reflection;
 | 
			
		||||
using System.Xml.Serialization;
 | 
			
		||||
 | 
			
		||||
namespace GameServiceWarden.Host.Preferences
 | 
			
		||||
namespace GameServiceWarden.Core.Preferences
 | 
			
		||||
{
 | 
			
		||||
    [Serializable]
 | 
			
		||||
    public class GeneralPreferences : IPersistable
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
namespace GameServiceWarden.Host.Preferences
 | 
			
		||||
namespace GameServiceWarden.Core.Preferences
 | 
			
		||||
{
 | 
			
		||||
    public interface IPersistable
 | 
			
		||||
    {
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
using System;
 | 
			
		||||
 | 
			
		||||
namespace GameServiceWarden.Host
 | 
			
		||||
namespace GameServiceWarden.Core
 | 
			
		||||
{
 | 
			
		||||
    class Program
 | 
			
		||||
    {
 | 
			
		||||
@@ -1,13 +1,13 @@
 | 
			
		||||
<mxfile host="65bd71144e" modified="2020-12-28T01:14:12.847Z" agent="5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Code/1.52.1 Chrome/83.0.4103.122 Electron/9.3.5 Safari/537.36" etag="ucZUuT6Z_sggXklr14bH" version="13.10.0" type="embed" pages="2">
 | 
			
		||||
<mxfile host="65bd71144e" modified="2020-12-28T04:29:17.687Z" agent="5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Code/1.52.1 Chrome/83.0.4103.122 Electron/9.3.5 Safari/537.36" etag="3-G5HDQr3muydbMwkt5P" version="13.10.0" type="embed" pages="2">
 | 
			
		||||
    <diagram id="LHR7ubqCPd17_LyHkaH9" name="Structure">
 | 
			
		||||
        <mxGraphModel dx="1009" dy="418" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0">
 | 
			
		||||
        <mxGraphModel dx="1298" dy="740" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0">
 | 
			
		||||
            <root>
 | 
			
		||||
                <mxCell id="0"/>
 | 
			
		||||
                <mxCell id="1" parent="0"/>
 | 
			
		||||
                <mxCell id="dmd0HlDYcxYugIlahWj0-10" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.75;exitY=0;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;dashed=1;endArrow=block;endFill=0;sketch=1;" parent="1" source="dmd0HlDYcxYugIlahWj0-5" target="dmd0HlDYcxYugIlahWj0-9" edge="1">
 | 
			
		||||
                    <mxGeometry relative="1" as="geometry"/>
 | 
			
		||||
                </mxCell>
 | 
			
		||||
                <mxCell id="dmd0HlDYcxYugIlahWj0-5" value="ServiceInfo" style="swimlane;fontStyle=1;align=center;verticalAlign=top;childLayout=stackLayout;horizontal=1;startSize=26;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;sketch=1;" parent="1" vertex="1">
 | 
			
		||||
                <mxCell id="dmd0HlDYcxYugIlahWj0-5" value="GameServiceInfo" style="swimlane;fontStyle=1;align=center;verticalAlign=top;childLayout=stackLayout;horizontal=1;startSize=26;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;sketch=1;" parent="1" vertex="1">
 | 
			
		||||
                    <mxGeometry x="762" y="1030" width="401" height="400" as="geometry"/>
 | 
			
		||||
                </mxCell>
 | 
			
		||||
                <mxCell id="dmd0HlDYcxYugIlahWj0-6" value="- serviceName: string
- controlLock: object
- state: ServiceState
- service: IGameService
- serviceConsoleStream: Stream
- moduleName: string
- assemblyName: string
- Dictionary<string, IConfigurable>
- disposed: bool" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=top;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;sketch=1;" parent="dmd0HlDYcxYugIlahWj0-5" vertex="1">
 | 
			
		||||
@@ -40,7 +40,7 @@
 | 
			
		||||
                <mxCell id="SI3d9EEbteElKQB4Ic5T-14" value="Use" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;endArrow=open;endFill=0;sketch=1;" parent="1" source="dmd0HlDYcxYugIlahWj0-11" target="SI3d9EEbteElKQB4Ic5T-10" edge="1">
 | 
			
		||||
                    <mxGeometry relative="1" as="geometry"/>
 | 
			
		||||
                </mxCell>
 | 
			
		||||
                <mxCell id="dmd0HlDYcxYugIlahWj0-11" value="ServiceManager" style="swimlane;fontStyle=1;align=center;verticalAlign=top;childLayout=stackLayout;horizontal=1;startSize=26;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;sketch=1;" parent="1" vertex="1">
 | 
			
		||||
                <mxCell id="dmd0HlDYcxYugIlahWj0-11" value="GameServiceManager" style="swimlane;fontStyle=1;align=center;verticalAlign=top;childLayout=stackLayout;horizontal=1;startSize=26;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;sketch=1;" parent="1" vertex="1">
 | 
			
		||||
                    <mxGeometry x="722" y="670" width="481" height="280" as="geometry">
 | 
			
		||||
                        <mxRectangle x="25" y="490" width="120" height="26" as="alternateBounds"/>
 | 
			
		||||
                    </mxGeometry>
 | 
			
		||||
@@ -54,7 +54,7 @@
 | 
			
		||||
                <mxCell id="dmd0HlDYcxYugIlahWj0-14" value="+ AddModule(assemblyName: string, module: IGameServiceModule): void
+ RemoveModule(assemblyName: string, moduleName string): void
+ CreateService(serviceName: string, assemblyName: string, moduleName: string): void
+ DeleteService(serviceName: string): void
+ GetServiceNames(): IReadOnlyCollection<string>
+ GetServiceOptionsValue(serviceName: string): IEnumerable<string>
+ SetServiceOptionValue(serviceName: string, optionName: string, string: value): bool
+ GetServiceState(serviceName: string): ServiceState
+ StartService(serviceName: string): void
+ StopService(serviceName: string): void
+ ExecuteCommand(serviceName: string, command: string): void
+ GetServiceConsoleStream(): Stream
+ ExecuteServiceAction(serviceAction: serviceAction): void" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=top;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;sketch=1;" parent="dmd0HlDYcxYugIlahWj0-11" vertex="1">
 | 
			
		||||
                    <mxGeometry y="78" width="481" height="202" as="geometry"/>
 | 
			
		||||
                </mxCell>
 | 
			
		||||
                <mxCell id="dmd0HlDYcxYugIlahWj0-16" value="ModuleLoader" style="swimlane;fontStyle=1;align=center;verticalAlign=top;childLayout=stackLayout;horizontal=1;startSize=26;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;sketch=1;" parent="1" vertex="1">
 | 
			
		||||
                <mxCell id="dmd0HlDYcxYugIlahWj0-16" value="GameModuleLoader" style="swimlane;fontStyle=1;align=center;verticalAlign=top;childLayout=stackLayout;horizontal=1;startSize=26;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;sketch=1;" parent="1" vertex="1">
 | 
			
		||||
                    <mxGeometry x="1700" y="490" width="460" height="140" as="geometry"/>
 | 
			
		||||
                </mxCell>
 | 
			
		||||
                <mxCell id="dmd0HlDYcxYugIlahWj0-17" value="- dataDirectory: string" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=top;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;sketch=1;" parent="dmd0HlDYcxYugIlahWj0-16" vertex="1">
 | 
			
		||||
@@ -66,8 +66,8 @@
 | 
			
		||||
                <mxCell id="dmd0HlDYcxYugIlahWj0-19" value="- InstantiateServiceables(assembly: Assembly): void
- LoadAssembly(path: string): void
+ LoadModules(path: string): IEnumerable<IGameServiceModule>
+ LoadAllModules(path: string[]): IEnumerable<IGameServiceModule>
+ LoadAllModules(path: IEnumerable<string>): IEnumerable<IGameServiceModule>" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=top;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;sketch=1;" parent="dmd0HlDYcxYugIlahWj0-16" vertex="1">
 | 
			
		||||
                    <mxGeometry y="60" width="460" height="80" as="geometry"/>
 | 
			
		||||
                </mxCell>
 | 
			
		||||
                <mxCell id="dmd0HlDYcxYugIlahWj0-20" value="ServiceGateway" style="swimlane;fontStyle=1;align=center;verticalAlign=top;childLayout=stackLayout;horizontal=1;startSize=26;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;sketch=1;" parent="1" vertex="1">
 | 
			
		||||
                    <mxGeometry x="2590" y="490" width="440" height="130" as="geometry"/>
 | 
			
		||||
                <mxCell id="dmd0HlDYcxYugIlahWj0-20" value="GameServiceGateway" style="swimlane;fontStyle=1;align=center;verticalAlign=top;childLayout=stackLayout;horizontal=1;startSize=26;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;sketch=1;" parent="1" vertex="1">
 | 
			
		||||
                    <mxGeometry x="2190" y="490" width="440" height="130" as="geometry"/>
 | 
			
		||||
                </mxCell>
 | 
			
		||||
                <mxCell id="dmd0HlDYcxYugIlahWj0-21" value="- dataDirectory: string" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=top;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;sketch=1;" parent="dmd0HlDYcxYugIlahWj0-20" vertex="1">
 | 
			
		||||
                    <mxGeometry y="26" width="440" height="26" as="geometry"/>
 | 
			
		||||
@@ -79,7 +79,7 @@
 | 
			
		||||
                    <mxGeometry y="60" width="440" height="70" as="geometry"/>
 | 
			
		||||
                </mxCell>
 | 
			
		||||
                <mxCell id="dmd0HlDYcxYugIlahWj0-38" value="<<Interface>>
ITextCommand" style="swimlane;fontStyle=1;align=center;verticalAlign=top;childLayout=stackLayout;horizontal=1;startSize=40;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;sketch=1;" parent="1" vertex="1">
 | 
			
		||||
                    <mxGeometry x="1285" y="28" width="181" height="114" as="geometry"/>
 | 
			
		||||
                    <mxGeometry x="1285" y="138" width="181" height="114" as="geometry"/>
 | 
			
		||||
                </mxCell>
 | 
			
		||||
                <mxCell id="dmd0HlDYcxYugIlahWj0-40" value="" style="line;strokeWidth=1;fillColor=none;align=left;verticalAlign=middle;spacingTop=-1;spacingLeft=3;spacingRight=3;rotatable=0;labelPosition=right;points=[];portConstraint=eastwest;sketch=1;" parent="dmd0HlDYcxYugIlahWj0-38" vertex="1">
 | 
			
		||||
                    <mxGeometry y="40" width="181" height="8" as="geometry"/>
 | 
			
		||||
@@ -88,7 +88,7 @@
 | 
			
		||||
                    <mxGeometry y="48" width="181" height="66" as="geometry"/>
 | 
			
		||||
                </mxCell>
 | 
			
		||||
                <mxCell id="2br9O0FZKGLhbr8u3XJU-1" value="ConsoleView" style="swimlane;fontStyle=1;align=center;verticalAlign=top;childLayout=stackLayout;horizontal=1;startSize=26;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;sketch=1;" parent="1" vertex="1">
 | 
			
		||||
                    <mxGeometry x="870" width="200" height="104" as="geometry"/>
 | 
			
		||||
                    <mxGeometry x="850" y="30" width="200" height="104" as="geometry"/>
 | 
			
		||||
                </mxCell>
 | 
			
		||||
                <mxCell id="2br9O0FZKGLhbr8u3XJU-2" value="- mainController: ITextCommand
- mainPresenter: ITextOutput" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=top;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;sketch=1;" parent="2br9O0FZKGLhbr8u3XJU-1" vertex="1">
 | 
			
		||||
                    <mxGeometry y="26" width="200" height="44" as="geometry"/>
 | 
			
		||||
@@ -104,11 +104,11 @@
 | 
			
		||||
                </mxCell>
 | 
			
		||||
                <mxCell id="wwlaSBDwwZOn0hO83bWU-10" value="Use" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;dashed=1;endArrow=open;endFill=0;sketch=1;" parent="1" source="qpeZJq-dxPH0P0VpmRa_-7" target="dmd0HlDYcxYugIlahWj0-38" edge="1">
 | 
			
		||||
                    <mxGeometry relative="1" as="geometry">
 | 
			
		||||
                        <mxPoint x="950" y="82" as="targetPoint"/>
 | 
			
		||||
                        <mxPoint x="950" y="162" as="targetPoint"/>
 | 
			
		||||
                    </mxGeometry>
 | 
			
		||||
                </mxCell>
 | 
			
		||||
                <mxCell id="qpeZJq-dxPH0P0VpmRa_-7" value="MainController" style="swimlane;fontStyle=1;align=center;verticalAlign=top;childLayout=stackLayout;horizontal=1;startSize=26;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;sketch=1;" parent="1" vertex="1">
 | 
			
		||||
                    <mxGeometry x="1505" y="110" width="270" height="60" as="geometry"/>
 | 
			
		||||
                    <mxGeometry x="1505" y="220" width="270" height="60" as="geometry"/>
 | 
			
		||||
                </mxCell>
 | 
			
		||||
                <mxCell id="qpeZJq-dxPH0P0VpmRa_-8" value="+ commands: Dictionary<string, ITextCommand>" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=top;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;sketch=1;" parent="qpeZJq-dxPH0P0VpmRa_-7" vertex="1">
 | 
			
		||||
                    <mxGeometry y="26" width="270" height="26" as="geometry"/>
 | 
			
		||||
@@ -125,8 +125,8 @@
 | 
			
		||||
                <mxCell id="V3nv0dmUtDNsDw_gxP-z-3" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;endArrow=open;endFill=0;sketch=1;" parent="1" source="K1k0_LUP-qlT_3mlrptx-2" target="dmd0HlDYcxYugIlahWj0-38" edge="1">
 | 
			
		||||
                    <mxGeometry relative="1" as="geometry"/>
 | 
			
		||||
                </mxCell>
 | 
			
		||||
                <mxCell id="K1k0_LUP-qlT_3mlrptx-2" value="ServiceController" style="swimlane;fontStyle=1;align=center;verticalAlign=top;childLayout=stackLayout;horizontal=1;startSize=26;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;sketch=1;" parent="1" vertex="1">
 | 
			
		||||
                    <mxGeometry x="1255" y="240" width="241" height="60" as="geometry"/>
 | 
			
		||||
                <mxCell id="K1k0_LUP-qlT_3mlrptx-2" value="GameServiceController" style="swimlane;fontStyle=1;align=center;verticalAlign=top;childLayout=stackLayout;horizontal=1;startSize=26;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;sketch=1;" parent="1" vertex="1">
 | 
			
		||||
                    <mxGeometry x="1255" y="320" width="241" height="60" as="geometry"/>
 | 
			
		||||
                </mxCell>
 | 
			
		||||
                <mxCell id="K1k0_LUP-qlT_3mlrptx-3" value="- serviceManipulator: IServiceManipulator" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=top;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;sketch=1;" parent="K1k0_LUP-qlT_3mlrptx-2" vertex="1">
 | 
			
		||||
                    <mxGeometry y="26" width="241" height="26" as="geometry"/>
 | 
			
		||||
@@ -137,8 +137,8 @@
 | 
			
		||||
                <mxCell id="wwlaSBDwwZOn0hO83bWU-16" value="Use" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;endArrow=open;endFill=0;sketch=1;" parent="1" source="wwlaSBDwwZOn0hO83bWU-2" target="wwlaSBDwwZOn0hO83bWU-12" edge="1">
 | 
			
		||||
                    <mxGeometry relative="1" as="geometry"/>
 | 
			
		||||
                </mxCell>
 | 
			
		||||
                <mxCell id="wwlaSBDwwZOn0hO83bWU-2" value="<<Interface>>
IServiceActionExecuter" style="swimlane;fontStyle=1;align=center;verticalAlign=top;childLayout=stackLayout;horizontal=1;startSize=40;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;sketch=1;" parent="1" vertex="1">
 | 
			
		||||
                    <mxGeometry x="1275" y="350" width="201" height="74" as="geometry"/>
 | 
			
		||||
                <mxCell id="wwlaSBDwwZOn0hO83bWU-2" value="<<Interface>>
IGameServiceActionExecuter" style="swimlane;fontStyle=1;align=center;verticalAlign=top;childLayout=stackLayout;horizontal=1;startSize=40;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;sketch=1;" parent="1" vertex="1">
 | 
			
		||||
                    <mxGeometry x="1275" y="480" width="201" height="74" as="geometry"/>
 | 
			
		||||
                </mxCell>
 | 
			
		||||
                <mxCell id="wwlaSBDwwZOn0hO83bWU-4" value="" style="line;strokeWidth=1;fillColor=none;align=left;verticalAlign=middle;spacingTop=-1;spacingLeft=3;spacingRight=3;rotatable=0;labelPosition=right;points=[];portConstraint=eastwest;sketch=1;" parent="wwlaSBDwwZOn0hO83bWU-2" vertex="1">
 | 
			
		||||
                    <mxGeometry y="40" width="201" height="8" as="geometry"/>
 | 
			
		||||
@@ -149,20 +149,17 @@
 | 
			
		||||
                <mxCell id="SI3d9EEbteElKQB4Ic5T-15" value="Use" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;endArrow=open;endFill=0;sketch=1;" parent="1" source="wwlaSBDwwZOn0hO83bWU-12" target="SI3d9EEbteElKQB4Ic5T-10" edge="1">
 | 
			
		||||
                    <mxGeometry relative="1" as="geometry"/>
 | 
			
		||||
                </mxCell>
 | 
			
		||||
                <mxCell id="wwlaSBDwwZOn0hO83bWU-12" value="<<DS>>
ServiceAction" style="swimlane;fontStyle=1;align=center;verticalAlign=top;childLayout=stackLayout;horizontal=1;startSize=40;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;sketch=1;" parent="1" vertex="1">
 | 
			
		||||
                    <mxGeometry x="1400" y="464" width="161" height="144" as="geometry"/>
 | 
			
		||||
                <mxCell id="wwlaSBDwwZOn0hO83bWU-12" value="<<DS>>
GameServiceAction" style="swimlane;fontStyle=1;align=center;verticalAlign=top;childLayout=stackLayout;horizontal=1;startSize=40;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;sketch=1;" parent="1" vertex="1">
 | 
			
		||||
                    <mxGeometry x="1466" y="600" width="161" height="128" as="geometry"/>
 | 
			
		||||
                </mxCell>
 | 
			
		||||
                <mxCell id="wwlaSBDwwZOn0hO83bWU-13" value="+ assemblyName: string
+ moduleName: string
+ serviceName: string
" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=top;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;sketch=1;" parent="wwlaSBDwwZOn0hO83bWU-12" vertex="1">
 | 
			
		||||
                    <mxGeometry y="40" width="161" height="70" as="geometry"/>
 | 
			
		||||
                <mxCell id="wwlaSBDwwZOn0hO83bWU-13" value="+ AssemblyName: string
+ ModuleName: string
+ ServiceName: string
+ Module: IModule
+ Action: ServiceActions" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=top;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;sketch=1;" parent="wwlaSBDwwZOn0hO83bWU-12" vertex="1">
 | 
			
		||||
                    <mxGeometry y="40" width="161" height="80" as="geometry"/>
 | 
			
		||||
                </mxCell>
 | 
			
		||||
                <mxCell id="wwlaSBDwwZOn0hO83bWU-14" value="" style="line;strokeWidth=1;fillColor=none;align=left;verticalAlign=middle;spacingTop=-1;spacingLeft=3;spacingRight=3;rotatable=0;labelPosition=right;points=[];portConstraint=eastwest;sketch=1;" parent="wwlaSBDwwZOn0hO83bWU-12" vertex="1">
 | 
			
		||||
                    <mxGeometry y="110" width="161" height="8" as="geometry"/>
 | 
			
		||||
                </mxCell>
 | 
			
		||||
                <mxCell id="wwlaSBDwwZOn0hO83bWU-15" value="+ method(type): type" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=top;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;sketch=1;" parent="wwlaSBDwwZOn0hO83bWU-12" vertex="1">
 | 
			
		||||
                    <mxGeometry y="118" width="161" height="26" as="geometry"/>
 | 
			
		||||
                    <mxGeometry y="120" width="161" height="8" as="geometry"/>
 | 
			
		||||
                </mxCell>
 | 
			
		||||
                <mxCell id="wwlaSBDwwZOn0hO83bWU-19" value="<<Interface>>
ITextOutput" style="swimlane;fontStyle=1;align=center;verticalAlign=top;childLayout=stackLayout;horizontal=1;startSize=40;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;sketch=1;" parent="1" vertex="1">
 | 
			
		||||
                    <mxGeometry x="340" y="33" width="310" height="110" as="geometry"/>
 | 
			
		||||
                    <mxGeometry x="340" y="137" width="310" height="110" as="geometry"/>
 | 
			
		||||
                </mxCell>
 | 
			
		||||
                <mxCell id="wwlaSBDwwZOn0hO83bWU-21" value="" style="line;strokeWidth=1;fillColor=none;align=left;verticalAlign=middle;spacingTop=-1;spacingLeft=3;spacingRight=3;rotatable=0;labelPosition=right;points=[];portConstraint=eastwest;sketch=1;" parent="wwlaSBDwwZOn0hO83bWU-19" vertex="1">
 | 
			
		||||
                    <mxGeometry y="40" width="310" height="8" as="geometry"/>
 | 
			
		||||
@@ -180,7 +177,7 @@
 | 
			
		||||
                    <mxGeometry relative="1" as="geometry"/>
 | 
			
		||||
                </mxCell>
 | 
			
		||||
                <mxCell id="HUSvFZX5SimreebZp30a-5" value="MainPresenter" style="swimlane;fontStyle=1;align=center;verticalAlign=top;childLayout=stackLayout;horizontal=1;startSize=26;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;sketch=1;" parent="1" vertex="1">
 | 
			
		||||
                    <mxGeometry x="30" y="110" width="270" height="60" as="geometry"/>
 | 
			
		||||
                    <mxGeometry x="30" y="214" width="270" height="60" as="geometry"/>
 | 
			
		||||
                </mxCell>
 | 
			
		||||
                <mxCell id="HUSvFZX5SimreebZp30a-6" value="- textPresenters: Dictionary<string, ITextOutput>" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=top;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;sketch=1;" parent="HUSvFZX5SimreebZp30a-5" vertex="1">
 | 
			
		||||
                    <mxGeometry y="26" width="270" height="26" as="geometry"/>
 | 
			
		||||
@@ -195,7 +192,7 @@
 | 
			
		||||
                    <mxGeometry relative="1" as="geometry"/>
 | 
			
		||||
                </mxCell>
 | 
			
		||||
                <mxCell id="HUSvFZX5SimreebZp30a-11" value="ServicePresenter" style="swimlane;fontStyle=1;align=center;verticalAlign=top;childLayout=stackLayout;horizontal=1;startSize=26;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;sketch=1;" parent="1" vertex="1">
 | 
			
		||||
                    <mxGeometry x="415" y="240" width="160" height="34" as="geometry"/>
 | 
			
		||||
                    <mxGeometry x="415" y="344" width="160" height="34" as="geometry"/>
 | 
			
		||||
                </mxCell>
 | 
			
		||||
                <mxCell id="HUSvFZX5SimreebZp30a-13" value="" style="line;strokeWidth=1;fillColor=none;align=left;verticalAlign=middle;spacingTop=-1;spacingLeft=3;spacingRight=3;rotatable=0;labelPosition=right;points=[];portConstraint=eastwest;sketch=1;" parent="HUSvFZX5SimreebZp30a-11" vertex="1">
 | 
			
		||||
                    <mxGeometry y="26" width="160" height="8" as="geometry"/>
 | 
			
		||||
@@ -203,8 +200,8 @@
 | 
			
		||||
                <mxCell id="SI3d9EEbteElKQB4Ic5T-5" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;endArrow=open;endFill=0;sketch=1;" parent="1" source="zFFzFwxISwJASp9ezwbr-1" target="fdKXkHfjRXYybK0fejAG-9" edge="1">
 | 
			
		||||
                    <mxGeometry relative="1" as="geometry"/>
 | 
			
		||||
                </mxCell>
 | 
			
		||||
                <mxCell id="zFFzFwxISwJASp9ezwbr-1" value="<<Interface>>
IServiceOutputMonitor" style="swimlane;fontStyle=1;align=center;verticalAlign=top;childLayout=stackLayout;horizontal=1;startSize=40;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;sketch=1;" parent="1" vertex="1">
 | 
			
		||||
                    <mxGeometry x="355" y="360" width="280" height="74" as="geometry"/>
 | 
			
		||||
                <mxCell id="zFFzFwxISwJASp9ezwbr-1" value="<<Interface>>
IGameServiceOutputMonitor" style="swimlane;fontStyle=1;align=center;verticalAlign=top;childLayout=stackLayout;horizontal=1;startSize=40;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;sketch=1;" parent="1" vertex="1">
 | 
			
		||||
                    <mxGeometry x="355" y="464" width="280" height="74" as="geometry"/>
 | 
			
		||||
                </mxCell>
 | 
			
		||||
                <mxCell id="zFFzFwxISwJASp9ezwbr-3" value="" style="line;strokeWidth=1;fillColor=none;align=left;verticalAlign=middle;spacingTop=-1;spacingLeft=3;spacingRight=3;rotatable=0;labelPosition=right;points=[];portConstraint=eastwest;sketch=1;" parent="zFFzFwxISwJASp9ezwbr-1" vertex="1">
 | 
			
		||||
                    <mxGeometry y="40" width="280" height="8" as="geometry"/>
 | 
			
		||||
@@ -212,17 +209,17 @@
 | 
			
		||||
                <mxCell id="zFFzFwxISwJASp9ezwbr-4" value="+ ServicesChanged(ServicesResult results): void" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=top;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;sketch=1;" parent="zFFzFwxISwJASp9ezwbr-1" vertex="1">
 | 
			
		||||
                    <mxGeometry y="48" width="280" height="26" as="geometry"/>
 | 
			
		||||
                </mxCell>
 | 
			
		||||
                <mxCell id="fdKXkHfjRXYybK0fejAG-9" value="<<DS>>
ServicesResults" style="swimlane;fontStyle=1;align=center;verticalAlign=top;childLayout=stackLayout;horizontal=1;startSize=40;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;sketch=1;" parent="1" vertex="1">
 | 
			
		||||
                    <mxGeometry x="320" y="860" width="350" height="138" as="geometry"/>
 | 
			
		||||
                <mxCell id="fdKXkHfjRXYybK0fejAG-9" value="<<DS>>
GameServicesActionResults" style="swimlane;fontStyle=1;align=center;verticalAlign=top;childLayout=stackLayout;horizontal=1;startSize=40;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;sketch=1;" parent="1" vertex="1">
 | 
			
		||||
                    <mxGeometry x="225" y="830" width="365" height="138" as="geometry"/>
 | 
			
		||||
                </mxCell>
 | 
			
		||||
                <mxCell id="fdKXkHfjRXYybK0fejAG-10" value="+ Services: ICollection<string>
+ Running: ICollection<string>
+ Errors: ICollection<string>
+ Consoles: IDictionary<string, Stream>
+ ServiceOptions: IDictionary<string, IDictionary<string, string>>" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=top;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;sketch=1;" parent="fdKXkHfjRXYybK0fejAG-9" vertex="1">
 | 
			
		||||
                    <mxGeometry y="40" width="350" height="90" as="geometry"/>
 | 
			
		||||
                    <mxGeometry y="40" width="365" height="90" as="geometry"/>
 | 
			
		||||
                </mxCell>
 | 
			
		||||
                <mxCell id="fdKXkHfjRXYybK0fejAG-11" value="" style="line;strokeWidth=1;fillColor=none;align=left;verticalAlign=middle;spacingTop=-1;spacingLeft=3;spacingRight=3;rotatable=0;labelPosition=right;points=[];portConstraint=eastwest;sketch=1;" parent="fdKXkHfjRXYybK0fejAG-9" vertex="1">
 | 
			
		||||
                    <mxGeometry y="130" width="350" height="8" as="geometry"/>
 | 
			
		||||
                    <mxGeometry y="130" width="365" height="8" as="geometry"/>
 | 
			
		||||
                </mxCell>
 | 
			
		||||
                <mxCell id="SI3d9EEbteElKQB4Ic5T-10" value="<<Enum>>
ServiceActions" style="swimlane;fontStyle=1;align=center;verticalAlign=top;childLayout=stackLayout;horizontal=1;startSize=40;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;sketch=1;" parent="1" vertex="1">
 | 
			
		||||
                    <mxGeometry x="882.5" y="442" width="160" height="188" as="geometry"/>
 | 
			
		||||
                <mxCell id="SI3d9EEbteElKQB4Ic5T-10" value="<<Enum>>
GameServiceActions" style="swimlane;fontStyle=1;align=center;verticalAlign=top;childLayout=stackLayout;horizontal=1;startSize=40;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;sketch=1;" parent="1" vertex="1">
 | 
			
		||||
                    <mxGeometry x="882.5" y="420" width="160" height="188" as="geometry"/>
 | 
			
		||||
                </mxCell>
 | 
			
		||||
                <mxCell id="SI3d9EEbteElKQB4Ic5T-11" value="+ Start
+ Stop
+ AddModule
+ RemoveModule
+ CreateService
+ DeleteService
+ Execute
+ SetServiceOption
+ View" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=top;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;sketch=1;" parent="SI3d9EEbteElKQB4Ic5T-10" vertex="1">
 | 
			
		||||
                    <mxGeometry y="40" width="160" height="140" as="geometry"/>
 | 
			
		||||
@@ -234,176 +231,348 @@
 | 
			
		||||
        </mxGraphModel>
 | 
			
		||||
    </diagram>
 | 
			
		||||
    <diagram id="gj0qHRc3eh050ABAey3g" name="Data-Flow">
 | 
			
		||||
        
        


 | 
			
		||||
        <mxGraphModel dx="1009" dy="418" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0">
 | 
			
		||||
            
            


 | 
			
		||||
            <root>
 | 
			
		||||
                
                


 | 
			
		||||
                <mxCell id="jVG6p58vlRYGO9X4wXeX-0"/>
 | 
			
		||||
                
                


 | 
			
		||||
                <mxCell id="jVG6p58vlRYGO9X4wXeX-1" parent="jVG6p58vlRYGO9X4wXeX-0"/>
 | 
			
		||||
                
                


 | 
			
		||||
                <mxCell id="28FAlPysTx9DMYvLwa-2-21" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.3333333333333333;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0;entryY=0.75;entryDx=0;entryDy=0;endArrow=open;endFill=0;fillColor=#1ba1e2;strokeColor=#006EAF;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" source="jVG6p58vlRYGO9X4wXeX-2" target="jVG6p58vlRYGO9X4wXeX-3" edge="1">
 | 
			
		||||
                    
                    


 | 
			
		||||
                    <mxGeometry relative="1" as="geometry"/>
 | 
			
		||||
                    
                    


 | 
			
		||||
                </mxCell>
 | 
			
		||||
                
                


 | 
			
		||||
                <mxCell id="jVG6p58vlRYGO9X4wXeX-2" value="Actor" style="shape=umlActor;verticalLabelPosition=bottom;verticalAlign=top;html=1;outlineConnect=0;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
 | 
			
		||||
                    
                    


 | 
			
		||||
                    <mxGeometry x="10" y="300" width="30" height="60" as="geometry"/>
 | 
			
		||||
                    
                    


 | 
			
		||||
                </mxCell>
 | 
			
		||||
                
                


 | 
			
		||||
                <mxCell id="jVG6p58vlRYGO9X4wXeX-12" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;endArrow=open;endFill=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;fillColor=#1ba1e2;strokeColor=#006EAF;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" source="jVG6p58vlRYGO9X4wXeX-3" target="jVG6p58vlRYGO9X4wXeX-4" edge="1">
 | 
			
		||||
                    
                    


 | 
			
		||||
                    <mxGeometry relative="1" as="geometry"/>
 | 
			
		||||
                    
                    


 | 
			
		||||
                </mxCell>
 | 
			
		||||
                
                


 | 
			
		||||
                <mxCell id="28FAlPysTx9DMYvLwa-2-22" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.25;exitDx=0;exitDy=0;entryX=0.75;entryY=0.1;entryDx=0;entryDy=0;entryPerimeter=0;endArrow=open;endFill=0;fillColor=#1ba1e2;strokeColor=#006EAF;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" source="jVG6p58vlRYGO9X4wXeX-3" target="jVG6p58vlRYGO9X4wXeX-2" edge="1">
 | 
			
		||||
                    
                    


 | 
			
		||||
                    <mxGeometry relative="1" as="geometry"/>
 | 
			
		||||
                    
                    


 | 
			
		||||
                </mxCell>
 | 
			
		||||
                
                


 | 
			
		||||
                <mxCell id="345FJoVc2gbAayMsQlD7-0" value="Use" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.25;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0.75;entryDx=0;entryDy=0;dashed=1;endArrow=open;endFill=0;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" source="jVG6p58vlRYGO9X4wXeX-3" target="jVG6p58vlRYGO9X4wXeX-4" edge="1">
 | 
			
		||||
                    
                    


 | 
			
		||||
                    <mxGeometry relative="1" as="geometry"/>
 | 
			
		||||
                    
                    


 | 
			
		||||
                </mxCell>
 | 
			
		||||
                
                


 | 
			
		||||
                <mxCell id="345FJoVc2gbAayMsQlD7-6" value="Use" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.25;exitY=0;exitDx=0;exitDy=0;entryX=0;entryY=0.25;entryDx=0;entryDy=0;dashed=1;endArrow=open;endFill=0;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" source="jVG6p58vlRYGO9X4wXeX-3" target="28FAlPysTx9DMYvLwa-2-7" edge="1">
 | 
			
		||||
                    
                    


 | 
			
		||||
                    <mxGeometry relative="1" as="geometry"/>
 | 
			
		||||
                    
                    


 | 
			
		||||
                </mxCell>
 | 
			
		||||
                
                


 | 
			
		||||
                <mxCell id="jVG6p58vlRYGO9X4wXeX-3" value="Console View" style="rounded=0;whiteSpace=wrap;html=1;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
 | 
			
		||||
                    
                    


 | 
			
		||||
                    <mxGeometry x="80" y="300" width="120" height="60" as="geometry"/>
 | 
			
		||||
                    
                    


 | 
			
		||||
                </mxCell>
 | 
			
		||||
                
                


 | 
			
		||||
                <mxCell id="jVG6p58vlRYGO9X4wXeX-13" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;endArrow=open;endFill=0;fillColor=#1ba1e2;strokeColor=#006EAF;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" source="jVG6p58vlRYGO9X4wXeX-4" target="jVG6p58vlRYGO9X4wXeX-5" edge="1">
 | 
			
		||||
                    
                    


 | 
			
		||||
                    <mxGeometry relative="1" as="geometry"/>
 | 
			
		||||
                    
                    


 | 
			
		||||
                </mxCell>
 | 
			
		||||
                
                


 | 
			
		||||
                <mxCell id="345FJoVc2gbAayMsQlD7-2" value="Use" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.75;exitDx=0;exitDy=0;entryX=0;entryY=0.75;entryDx=0;entryDy=0;dashed=1;endArrow=open;endFill=0;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" source="jVG6p58vlRYGO9X4wXeX-4" target="jVG6p58vlRYGO9X4wXeX-5" edge="1">
 | 
			
		||||
                    
                    


 | 
			
		||||
                    <mxGeometry relative="1" as="geometry"/>
 | 
			
		||||
                    
                    


 | 
			
		||||
                </mxCell>
 | 
			
		||||
                
                


 | 
			
		||||
                <mxCell id="jVG6p58vlRYGO9X4wXeX-4" value="string command (request)" style="rounded=0;whiteSpace=wrap;html=1;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
 | 
			
		||||
                    
                    


 | 
			
		||||
                    <mxGeometry x="260" y="482.5" width="120" height="60" as="geometry"/>
 | 
			
		||||
                    
                    


 | 
			
		||||
                </mxCell>
 | 
			
		||||
                
                


 | 
			
		||||
                <mxCell id="jVG6p58vlRYGO9X4wXeX-8" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=1;entryDx=0;entryDy=0;dashed=1;endArrow=block;endFill=0;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" source="jVG6p58vlRYGO9X4wXeX-5" target="jVG6p58vlRYGO9X4wXeX-7" edge="1">
 | 
			
		||||
                    
                    


 | 
			
		||||
                    <mxGeometry relative="1" as="geometry"/>
 | 
			
		||||
                    
                    


 | 
			
		||||
                </mxCell>
 | 
			
		||||
                
                


 | 
			
		||||
                <mxCell id="28FAlPysTx9DMYvLwa-2-3" value="Use" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.75;exitY=0;exitDx=0;exitDy=0;entryX=0.75;entryY=1;entryDx=0;entryDy=0;endArrow=open;endFill=0;dashed=1;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" source="jVG6p58vlRYGO9X4wXeX-5" target="jVG6p58vlRYGO9X4wXeX-7" edge="1">
 | 
			
		||||
                    
                    


 | 
			
		||||
                    <mxGeometry relative="1" as="geometry"/>
 | 
			
		||||
                    
                    


 | 
			
		||||
                </mxCell>
 | 
			
		||||
                
                


 | 
			
		||||
                <mxCell id="UY-EM7-1ECCvWtENr50b-18" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;endArrow=open;endFill=0;strokeColor=#006EAF;fillColor=#1ba1e2;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" source="jVG6p58vlRYGO9X4wXeX-5" target="jVG6p58vlRYGO9X4wXeX-9" edge="1">
 | 
			
		||||
                    
                    


 | 
			
		||||
                    <mxGeometry relative="1" as="geometry"/>
 | 
			
		||||
                    
                    


 | 
			
		||||
                </mxCell>
 | 
			
		||||
                
                


 | 
			
		||||
                <mxCell id="jVG6p58vlRYGO9X4wXeX-5" value="MainController" style="rounded=0;whiteSpace=wrap;html=1;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
 | 
			
		||||
                    
                    


 | 
			
		||||
                    <mxGeometry x="420" y="482.5" width="120" height="60" as="geometry"/>
 | 
			
		||||
                    
                    


 | 
			
		||||
                </mxCell>
 | 
			
		||||
                
                


 | 
			
		||||
                <mxCell id="jVG6p58vlRYGO9X4wXeX-6" value="http://www.plainionist.net/Implementing-Clean-Architecture-Controller-Presenter/" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;whiteSpace=wrap;rounded=0;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
 | 
			
		||||
                    
                    


 | 
			
		||||
                    <mxGeometry y="840" width="480" height="20" as="geometry"/>
 | 
			
		||||
                    
                    


 | 
			
		||||
                </mxCell>
 | 
			
		||||
                
                


 | 
			
		||||
                <mxCell id="jVG6p58vlRYGO9X4wXeX-7" value="&lt;&lt;Interface&gt;&gt;<br>ICommand" style="rounded=0;whiteSpace=wrap;html=1;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
 | 
			
		||||
                    
                    


 | 
			
		||||
                    <mxGeometry x="420" y="372.5" width="120" height="60" as="geometry"/>
 | 
			
		||||
                    
                    


 | 
			
		||||
                </mxCell>
 | 
			
		||||
                
                


 | 
			
		||||
                <mxCell id="jVG6p58vlRYGO9X4wXeX-10" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=1;entryY=0.5;entryDx=0;entryDy=0;dashed=1;endArrow=block;endFill=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" source="jVG6p58vlRYGO9X4wXeX-9" target="jVG6p58vlRYGO9X4wXeX-7" edge="1">
 | 
			
		||||
                    
                    


 | 
			
		||||
                    <mxGeometry relative="1" as="geometry"/>
 | 
			
		||||
                    
                    


 | 
			
		||||
                </mxCell>
 | 
			
		||||
                
                


 | 
			
		||||
                <mxCell id="UY-EM7-1ECCvWtENr50b-8" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.25;entryDx=0;entryDy=0;endArrow=open;endFill=0;strokeColor=#006EAF;fillColor=#1ba1e2;exitX=1;exitY=0.5;exitDx=0;exitDy=0;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" source="jVG6p58vlRYGO9X4wXeX-9" target="UY-EM7-1ECCvWtENr50b-1" edge="1">
 | 
			
		||||
                    
                    


 | 
			
		||||
                    <mxGeometry relative="1" as="geometry">
 | 
			
		||||
                        
                        


 | 
			
		||||
                        <mxPoint x="809.9999999999998" y="512.5000000000002" as="sourcePoint"/>
 | 
			
		||||
                        
                        


 | 
			
		||||
                    </mxGeometry>
 | 
			
		||||
                    
                    


 | 
			
		||||
                </mxCell>
 | 
			
		||||
                
                


 | 
			
		||||
                <mxCell id="345FJoVc2gbAayMsQlD7-3" value="Use" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.25;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;dashed=1;endArrow=open;endFill=0;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" source="jVG6p58vlRYGO9X4wXeX-9" target="UY-EM7-1ECCvWtENr50b-2" edge="1">
 | 
			
		||||
                    
                    


 | 
			
		||||
                    <mxGeometry relative="1" as="geometry"/>
 | 
			
		||||
                    
                    


 | 
			
		||||
                </mxCell>
 | 
			
		||||
                
                


 | 
			
		||||
                <mxCell id="345FJoVc2gbAayMsQlD7-4" value="Use" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.75;exitDx=0;exitDy=0;entryX=0;entryY=0.75;entryDx=0;entryDy=0;dashed=1;endArrow=open;endFill=0;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" source="jVG6p58vlRYGO9X4wXeX-9" target="UY-EM7-1ECCvWtENr50b-1" edge="1">
 | 
			
		||||
                    
                    


 | 
			
		||||
                    <mxGeometry relative="1" as="geometry"/>
 | 
			
		||||
                    
                    


 | 
			
		||||
                </mxCell>
 | 
			
		||||
                
                


 | 
			
		||||
                <mxCell id="jVG6p58vlRYGO9X4wXeX-9" value="ServiceController" style="rounded=0;whiteSpace=wrap;html=1;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
 | 
			
		||||
                    
                    


 | 
			
		||||
                    <mxGeometry x="575" y="482.5" width="120" height="60" as="geometry"/>
 | 
			
		||||
                    
                    


 | 
			
		||||
                </mxCell>
 | 
			
		||||
                
                


 | 
			
		||||
                <mxCell id="UY-EM7-1ECCvWtENr50b-4" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=block;endFill=1;strokeColor=none;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" source="28FAlPysTx9DMYvLwa-2-1" target="UY-EM7-1ECCvWtENr50b-2" edge="1">
 | 
			
		||||
                    
                    


 | 
			
		||||
                    <mxGeometry relative="1" as="geometry"/>
 | 
			
		||||
                    
                    


 | 
			
		||||
                </mxCell>
 | 
			
		||||
                
                


 | 
			
		||||
                <mxCell id="UY-EM7-1ECCvWtENr50b-5" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;dashed=1;endArrow=block;endFill=0;strokeColor=#f0f0f0;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" source="28FAlPysTx9DMYvLwa-2-1" target="UY-EM7-1ECCvWtENr50b-2" edge="1">
 | 
			
		||||
                    
                    


 | 
			
		||||
                    <mxGeometry relative="1" as="geometry"/>
 | 
			
		||||
                    
                    


 | 
			
		||||
                </mxCell>
 | 
			
		||||
                
                


 | 
			
		||||
                <mxCell id="UY-EM7-1ECCvWtENr50b-7" value="Use" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=1.008;entryY=0.625;entryDx=0;entryDy=0;entryPerimeter=0;endArrow=open;endFill=0;strokeColor=#f0f0f0;dashed=1;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" source="28FAlPysTx9DMYvLwa-2-1" target="UY-EM7-1ECCvWtENr50b-1" edge="1">
 | 
			
		||||
                    
                    


 | 
			
		||||
                    <mxGeometry relative="1" as="geometry">
 | 
			
		||||
                        
                        


 | 
			
		||||
                        <Array as="points">
 | 
			
		||||
                            
                            


 | 
			
		||||
                            <mxPoint x="960" y="338"/>
 | 
			
		||||
                            
                            


 | 
			
		||||
                            <mxPoint x="960" y="580"/>
 | 
			
		||||
                            
                            


 | 
			
		||||
                        </Array>
 | 
			
		||||
                        
                        


 | 
			
		||||
                    </mxGeometry>
 | 
			
		||||
                    
                    


 | 
			
		||||
                </mxCell>
 | 
			
		||||
                
                


 | 
			
		||||
                <mxCell id="UY-EM7-1ECCvWtENr50b-16" value="Use" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=1;entryDx=0;entryDy=0;endArrow=open;endFill=0;dashed=1;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" source="28FAlPysTx9DMYvLwa-2-1" target="UY-EM7-1ECCvWtENr50b-11" edge="1">
 | 
			
		||||
                    
                    


 | 
			
		||||
                    <mxGeometry relative="1" as="geometry"/>
 | 
			
		||||
                    
                    


 | 
			
		||||
                </mxCell>
 | 
			
		||||
                
                


 | 
			
		||||
                <mxCell id="345FJoVc2gbAayMsQlD7-7" value="Use" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=1;entryY=0.25;entryDx=0;entryDy=0;dashed=1;endArrow=open;endFill=0;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" source="28FAlPysTx9DMYvLwa-2-1" target="UY-EM7-1ECCvWtENr50b-10" edge="1">
 | 
			
		||||
                    
                    


 | 
			
		||||
                    <mxGeometry relative="1" as="geometry">
 | 
			
		||||
                        
                        


 | 
			
		||||
                        <Array as="points">
 | 
			
		||||
                            
                            


 | 
			
		||||
                            <mxPoint x="960" y="338"/>
 | 
			
		||||
                            
                            


 | 
			
		||||
                            <mxPoint x="960" y="83"/>
 | 
			
		||||
                            
                            


 | 
			
		||||
                        </Array>
 | 
			
		||||
                        
                        


 | 
			
		||||
                    </mxGeometry>
 | 
			
		||||
                    
                    


 | 
			
		||||
                </mxCell>
 | 
			
		||||
                
                


 | 
			
		||||
                <mxCell id="28FAlPysTx9DMYvLwa-2-1" value="ServiceManager" style="rounded=0;whiteSpace=wrap;html=1;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
 | 
			
		||||
                    
                    


 | 
			
		||||
                    <mxGeometry x="800" y="307.5" width="120" height="60" as="geometry"/>
 | 
			
		||||
                    
                    


 | 
			
		||||
                </mxCell>
 | 
			
		||||
                
                


 | 
			
		||||
                <mxCell id="28FAlPysTx9DMYvLwa-2-9" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=1;entryY=0.5;entryDx=0;entryDy=0;endArrow=open;endFill=0;fillColor=#1ba1e2;strokeColor=#006EAF;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" source="28FAlPysTx9DMYvLwa-2-5" target="tM_Gde3HH8YiZ2frBV5J-0" edge="1">
 | 
			
		||||
                    
                    


 | 
			
		||||
                    <mxGeometry relative="1" as="geometry"/>
 | 
			
		||||
                    
                    


 | 
			
		||||
                </mxCell>
 | 
			
		||||
                
                


 | 
			
		||||
                <mxCell id="UY-EM7-1ECCvWtENr50b-12" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;endArrow=block;endFill=0;strokeColor=#f0f0f0;dashed=1;exitX=1;exitY=0.75;exitDx=0;exitDy=0;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" source="28FAlPysTx9DMYvLwa-2-5" target="UY-EM7-1ECCvWtENr50b-11" edge="1">
 | 
			
		||||
                    
                    


 | 
			
		||||
                    <mxGeometry relative="1" as="geometry"/>
 | 
			
		||||
                    
                    


 | 
			
		||||
                </mxCell>
 | 
			
		||||
                
                


 | 
			
		||||
                <mxCell id="UY-EM7-1ECCvWtENr50b-13" value="Use" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.75;entryDx=0;entryDy=0;endArrow=open;endFill=0;strokeColor=#f0f0f0;dashed=1;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" source="28FAlPysTx9DMYvLwa-2-5" target="UY-EM7-1ECCvWtENr50b-10" edge="1">
 | 
			
		||||
                    
                    


 | 
			
		||||
                    <mxGeometry relative="1" as="geometry"/>
 | 
			
		||||
                    
                    


 | 
			
		||||
                </mxCell>
 | 
			
		||||
                
                


 | 
			
		||||
                <mxCell id="tM_Gde3HH8YiZ2frBV5J-3" style="edgeStyle=orthogonalEdgeStyle;sketch=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;dashed=1;endArrow=block;endFill=0;" parent="jVG6p58vlRYGO9X4wXeX-1" source="28FAlPysTx9DMYvLwa-2-5" target="tM_Gde3HH8YiZ2frBV5J-1" edge="1">
 | 
			
		||||
                    
                    


 | 
			
		||||
                    <mxGeometry relative="1" as="geometry"/>
 | 
			
		||||
                    
                    


 | 
			
		||||
                </mxCell>
 | 
			
		||||
                
                


 | 
			
		||||
                <mxCell id="28FAlPysTx9DMYvLwa-2-5" value="ServicePresenter" style="rounded=0;whiteSpace=wrap;html=1;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
 | 
			
		||||
                    
                    


 | 
			
		||||
                    <mxGeometry x="575" y="122.5" width="120" height="60" as="geometry"/>
 | 
			
		||||
                    
                    


 | 
			
		||||
                </mxCell>
 | 
			
		||||
                
                


 | 
			
		||||
                <mxCell id="28FAlPysTx9DMYvLwa-2-8" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;endArrow=open;endFill=0;fillColor=#1ba1e2;strokeColor=#006EAF;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" source="28FAlPysTx9DMYvLwa-2-7" target="jVG6p58vlRYGO9X4wXeX-3" edge="1">
 | 
			
		||||
                    
                    


 | 
			
		||||
                    <mxGeometry relative="1" as="geometry"/>
 | 
			
		||||
                    
                    


 | 
			
		||||
                </mxCell>
 | 
			
		||||
                
                


 | 
			
		||||
                <mxCell id="tM_Gde3HH8YiZ2frBV5J-5" value="Use" style="edgeStyle=orthogonalEdgeStyle;sketch=1;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;dashed=1;endArrow=open;endFill=0;" parent="jVG6p58vlRYGO9X4wXeX-1" source="28FAlPysTx9DMYvLwa-2-7" target="tM_Gde3HH8YiZ2frBV5J-0" edge="1">
 | 
			
		||||
                    
                    


 | 
			
		||||
                    <mxGeometry relative="1" as="geometry"/>
 | 
			
		||||
                    
                    


 | 
			
		||||
                </mxCell>
 | 
			
		||||
                
                


 | 
			
		||||
                <mxCell id="28FAlPysTx9DMYvLwa-2-7" value="String Output" style="rounded=0;whiteSpace=wrap;html=1;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
 | 
			
		||||
                    
                    


 | 
			
		||||
                    <mxGeometry x="260" y="122.5" width="120" height="60" as="geometry"/>
 | 
			
		||||
                    
                    


 | 
			
		||||
                </mxCell>
 | 
			
		||||
                
                


 | 
			
		||||
                <mxCell id="UY-EM7-1ECCvWtENr50b-1" value="ServiceAction &lt;DS&gt;" style="rounded=0;whiteSpace=wrap;html=1;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
 | 
			
		||||
                    
                    


 | 
			
		||||
                    <mxGeometry x="800" y="542.5" width="120" height="60" as="geometry"/>
 | 
			
		||||
                    
                    


 | 
			
		||||
                </mxCell>
 | 
			
		||||
                
                


 | 
			
		||||
                <mxCell id="UY-EM7-1ECCvWtENr50b-6" value="Use" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;endArrow=open;endFill=0;strokeColor=#f0f0f0;dashed=1;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" source="UY-EM7-1ECCvWtENr50b-2" target="UY-EM7-1ECCvWtENr50b-1" edge="1">
 | 
			
		||||
                    
                    


 | 
			
		||||
                    <mxGeometry relative="1" as="geometry"/>
 | 
			
		||||
                    
                    


 | 
			
		||||
                </mxCell>
 | 
			
		||||
                
                


 | 
			
		||||
                <mxCell id="UY-EM7-1ECCvWtENr50b-20" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.25;exitDx=0;exitDy=0;entryX=1;entryY=0.75;entryDx=0;entryDy=0;endArrow=open;endFill=0;strokeColor=#006EAF;fillColor=#1ba1e2;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" source="UY-EM7-1ECCvWtENr50b-1" target="28FAlPysTx9DMYvLwa-2-1" edge="1">
 | 
			
		||||
                    
                    


 | 
			
		||||
                    <mxGeometry relative="1" as="geometry"/>
 | 
			
		||||
                    
                    


 | 
			
		||||
                </mxCell>
 | 
			
		||||
                
                


 | 
			
		||||
                <mxCell id="UY-EM7-1ECCvWtENr50b-2" value="&lt;&lt;Interface&gt;&gt;<br>IServiceManipulator" style="rounded=0;whiteSpace=wrap;html=1;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
 | 
			
		||||
                    
                    


 | 
			
		||||
                    <mxGeometry x="800" y="432.5" width="120" height="60" as="geometry"/>
 | 
			
		||||
                    
                    


 | 
			
		||||
                </mxCell>
 | 
			
		||||
                
                


 | 
			
		||||
                <mxCell id="UY-EM7-1ECCvWtENr50b-22" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=1;entryY=0.25;entryDx=0;entryDy=0;endArrow=open;endFill=0;strokeColor=#006EAF;fillColor=#1ba1e2;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" source="UY-EM7-1ECCvWtENr50b-10" target="28FAlPysTx9DMYvLwa-2-5" edge="1">
 | 
			
		||||
                    
                    


 | 
			
		||||
                    <mxGeometry relative="1" as="geometry"/>
 | 
			
		||||
                    
                    


 | 
			
		||||
                </mxCell>
 | 
			
		||||
                
                


 | 
			
		||||
                <mxCell id="UY-EM7-1ECCvWtENr50b-10" value="ServicesResult &lt;DS&gt;" style="rounded=0;whiteSpace=wrap;html=1;fillColor=none;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
 | 
			
		||||
                    
                    


 | 
			
		||||
                    <mxGeometry x="800" y="67.5" width="120" height="60" as="geometry"/>
 | 
			
		||||
                    
                    


 | 
			
		||||
                </mxCell>
 | 
			
		||||
                
                


 | 
			
		||||
                <mxCell id="UY-EM7-1ECCvWtENr50b-14" value="Use" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=1;entryDx=0;entryDy=0;endArrow=open;endFill=0;strokeColor=#f0f0f0;dashed=1;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" source="UY-EM7-1ECCvWtENr50b-11" target="UY-EM7-1ECCvWtENr50b-10" edge="1">
 | 
			
		||||
                    
                    


 | 
			
		||||
                    <mxGeometry relative="1" as="geometry"/>
 | 
			
		||||
                    
                    


 | 
			
		||||
                </mxCell>
 | 
			
		||||
                
                


 | 
			
		||||
                <mxCell id="UY-EM7-1ECCvWtENr50b-21" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.25;exitDx=0;exitDy=0;entryX=1;entryY=0.75;entryDx=0;entryDy=0;endArrow=open;endFill=0;strokeColor=#006EAF;fillColor=#1ba1e2;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" source="28FAlPysTx9DMYvLwa-2-1" target="UY-EM7-1ECCvWtENr50b-10" edge="1">
 | 
			
		||||
                    
                    


 | 
			
		||||
                    <mxGeometry relative="1" as="geometry"/>
 | 
			
		||||
                    
                    


 | 
			
		||||
                </mxCell>
 | 
			
		||||
                
                


 | 
			
		||||
                <mxCell id="UY-EM7-1ECCvWtENr50b-11" value="&lt;&lt;Interface&gt;&gt;<br>IServicesMonitor" style="rounded=0;whiteSpace=wrap;html=1;fillColor=none;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
 | 
			
		||||
                    
                    


 | 
			
		||||
                    <mxGeometry x="800" y="167.5" width="120" height="60" as="geometry"/>
 | 
			
		||||
                    
                    


 | 
			
		||||
                </mxCell>
 | 
			
		||||
                
                


 | 
			
		||||
                <mxCell id="UY-EM7-1ECCvWtENr50b-70" value="" style="line;strokeWidth=2;direction=south;html=1;fillColor=none;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
 | 
			
		||||
                    
                    


 | 
			
		||||
                    <mxGeometry x="220" y="50" width="10" height="570" as="geometry"/>
 | 
			
		||||
                    
                    


 | 
			
		||||
                </mxCell>
 | 
			
		||||
                
                


 | 
			
		||||
                <mxCell id="UY-EM7-1ECCvWtENr50b-71" value="" style="line;strokeWidth=2;direction=south;html=1;fillColor=none;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
 | 
			
		||||
                    
                    


 | 
			
		||||
                    <mxGeometry x="760" y="50" width="10" height="570" as="geometry"/>
 | 
			
		||||
                    
                    


 | 
			
		||||
                </mxCell>
 | 
			
		||||
                
                


 | 
			
		||||
                <mxCell id="UY-EM7-1ECCvWtENr50b-73" value="Page 191 (Chapter 22) of Clean Architecture" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;whiteSpace=wrap;rounded=0;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
 | 
			
		||||
                    
                    


 | 
			
		||||
                    <mxGeometry y="870" width="480" height="20" as="geometry"/>
 | 
			
		||||
                    
                    


 | 
			
		||||
                </mxCell>
 | 
			
		||||
                
                


 | 
			
		||||
                <mxCell id="tM_Gde3HH8YiZ2frBV5J-2" style="edgeStyle=orthogonalEdgeStyle;sketch=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;dashed=1;endArrow=block;endFill=0;" parent="jVG6p58vlRYGO9X4wXeX-1" source="tM_Gde3HH8YiZ2frBV5J-0" target="tM_Gde3HH8YiZ2frBV5J-1" edge="1">
 | 
			
		||||
                    
                    


 | 
			
		||||
                    <mxGeometry relative="1" as="geometry"/>
 | 
			
		||||
                    
                    


 | 
			
		||||
                </mxCell>
 | 
			
		||||
                
                


 | 
			
		||||
                <mxCell id="tM_Gde3HH8YiZ2frBV5J-4" value="Use" style="edgeStyle=orthogonalEdgeStyle;sketch=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.75;exitY=0;exitDx=0;exitDy=0;entryX=0.75;entryY=1;entryDx=0;entryDy=0;dashed=1;endArrow=open;endFill=0;" parent="jVG6p58vlRYGO9X4wXeX-1" source="tM_Gde3HH8YiZ2frBV5J-0" target="tM_Gde3HH8YiZ2frBV5J-1" edge="1">
 | 
			
		||||
                    
                    


 | 
			
		||||
                    <mxGeometry relative="1" as="geometry"/>
 | 
			
		||||
                    
                    


 | 
			
		||||
                </mxCell>
 | 
			
		||||
                
                


 | 
			
		||||
                <mxCell id="tM_Gde3HH8YiZ2frBV5J-0" value="MainPresenter" style="html=1;dashed=0;whitespace=wrap;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
 | 
			
		||||
                    
                    


 | 
			
		||||
                    <mxGeometry x="420" y="122.5" width="110" height="60" as="geometry"/>
 | 
			
		||||
                    
                    


 | 
			
		||||
                </mxCell>
 | 
			
		||||
                
                


 | 
			
		||||
                <mxCell id="tM_Gde3HH8YiZ2frBV5J-1" value="&lt;&lt;Interface&gt;&gt;<br>IConsoleOutput" style="html=1;dashed=0;whitespace=wrap;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
 | 
			
		||||
                    
                    


 | 
			
		||||
                    <mxGeometry x="420" y="20" width="110" height="50" as="geometry"/>
 | 
			
		||||
                    
                    


 | 
			
		||||
                </mxCell>
 | 
			
		||||
                
                


 | 
			
		||||
            </root>
 | 
			
		||||
            
            


 | 
			
		||||
        </mxGraphModel>
 | 
			
		||||
        
        


 | 
			
		||||
    </diagram>
 | 
			
		||||
</mxfile>
 | 
			
		||||
@@ -1,13 +0,0 @@
 | 
			
		||||
namespace GameServiceWarden.Host.Modules.Exceptions
 | 
			
		||||
{
 | 
			
		||||
    [System.Serializable]
 | 
			
		||||
    public class CorruptedServiceInfoException : System.Exception
 | 
			
		||||
    {
 | 
			
		||||
        public CorruptedServiceInfoException() { }
 | 
			
		||||
        public CorruptedServiceInfoException(string message) : base(message) { }
 | 
			
		||||
        public CorruptedServiceInfoException(string message, System.Exception inner) : base(message, inner) { }
 | 
			
		||||
        protected CorruptedServiceInfoException(
 | 
			
		||||
            System.Runtime.Serialization.SerializationInfo info,
 | 
			
		||||
            System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,17 +0,0 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Reflection;
 | 
			
		||||
using System.Runtime.Serialization;
 | 
			
		||||
 | 
			
		||||
namespace GameServiceWarden.Host.Modules.Exceptions
 | 
			
		||||
{
 | 
			
		||||
    [Serializable]
 | 
			
		||||
    public class NoServiceableFoundException : Exception
 | 
			
		||||
    {
 | 
			
		||||
        public NoServiceableFoundException(string message) : base(message) { }
 | 
			
		||||
        public NoServiceableFoundException(string message, Exception inner) : base(message, inner) { }
 | 
			
		||||
        protected NoServiceableFoundException(
 | 
			
		||||
            SerializationInfo info,
 | 
			
		||||
            StreamingContext context) : base(info, context) { }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,15 +0,0 @@
 | 
			
		||||
using System;
 | 
			
		||||
 | 
			
		||||
namespace GameServiceWarden.Host.Modules.Exceptions
 | 
			
		||||
{
 | 
			
		||||
    [System.Serializable]
 | 
			
		||||
    public class NotServiceableTypeException : Exception
 | 
			
		||||
    {
 | 
			
		||||
        public NotServiceableTypeException() { }
 | 
			
		||||
        public NotServiceableTypeException(string message) : base(message) { }
 | 
			
		||||
        public NotServiceableTypeException(string message, System.Exception inner) : base(message, inner) { }
 | 
			
		||||
        protected NotServiceableTypeException(
 | 
			
		||||
            System.Runtime.Serialization.SerializationInfo info,
 | 
			
		||||
            System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
namespace GameServiceWarden.ModuleAPI
 | 
			
		||||
{
 | 
			
		||||
    public interface IConfigurable
 | 
			
		||||
    public interface IGameConfigurable
 | 
			
		||||
    {
 | 
			
		||||
        string OptionName { get; }
 | 
			
		||||
        bool SetValue(string value);
 | 
			
		||||
@@ -7,7 +7,7 @@ namespace GameServiceWarden.ModuleAPI
 | 
			
		||||
    public interface IGameService
 | 
			
		||||
    {
 | 
			
		||||
        event EventHandler<ServiceState> StateChangeEvent;
 | 
			
		||||
        IReadOnlyCollection<IConfigurable> Configurables{ get; }
 | 
			
		||||
        IReadOnlyCollection<IGameConfigurable> Configurables{ get; }
 | 
			
		||||
        void InitializeService(TextWriter stream);
 | 
			
		||||
        void ElegantShutdown();
 | 
			
		||||
        void ExecuteCommand(string command);
 | 
			
		||||
 
 | 
			
		||||
@@ -14,7 +14,7 @@
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <ProjectReference Include="..\..\src\GameServiceWarden.Host\GameServiceWarden.Host.csproj" />
 | 
			
		||||
    <ProjectReference Include="..\..\src\GameServiceWarden.Core\GameServiceWarden.Core.csproj" />
 | 
			
		||||
    <ProjectReference Include="..\..\src\GameServiceWarden.ModuleAPI\GameServiceWarden.ModuleAPI.csproj" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
 | 
			
		||||
@@ -1,13 +1,13 @@
 | 
			
		||||
using GameServiceWarden.ModuleAPI;
 | 
			
		||||
 | 
			
		||||
namespace GameServiceWarden.Host.Tests.Modules
 | 
			
		||||
namespace GameServiceWarden.Core.Tests.Modules.Games
 | 
			
		||||
{
 | 
			
		||||
    public class FakeConfigurable : IConfigurable
 | 
			
		||||
    public class FakeGameConfigurable : IGameConfigurable
 | 
			
		||||
    {
 | 
			
		||||
        private string value;
 | 
			
		||||
        public string OptionName { get; private set; }
 | 
			
		||||
 | 
			
		||||
        public FakeConfigurable(string optionName)
 | 
			
		||||
        public FakeGameConfigurable(string optionName)
 | 
			
		||||
        {
 | 
			
		||||
            this.OptionName = optionName;
 | 
			
		||||
        }
 | 
			
		||||
@@ -3,11 +3,11 @@ using System.Collections.Generic;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using GameServiceWarden.ModuleAPI;
 | 
			
		||||
 | 
			
		||||
namespace GameServiceWarden.Host.Tests.Modules
 | 
			
		||||
namespace GameServiceWarden.Core.Tests.Modules.Games
 | 
			
		||||
{
 | 
			
		||||
    public class FakeService : IGameService
 | 
			
		||||
    public class FakeGameService : IGameService
 | 
			
		||||
    {
 | 
			
		||||
        public IReadOnlyCollection<IConfigurable> Configurables { get; set; }
 | 
			
		||||
        public IReadOnlyCollection<IGameConfigurable> Configurables { get; set; }
 | 
			
		||||
 | 
			
		||||
        public event EventHandler<ServiceState> StateChangeEvent;
 | 
			
		||||
 | 
			
		||||
@@ -15,10 +15,10 @@ namespace GameServiceWarden.Host.Tests.Modules
 | 
			
		||||
 | 
			
		||||
        private TextWriter consoleStream;
 | 
			
		||||
 | 
			
		||||
        public FakeService(params IConfigurable[] configurables)
 | 
			
		||||
        public FakeGameService(params IGameConfigurable[] configurables)
 | 
			
		||||
        {
 | 
			
		||||
            HashSet<IConfigurable> modifiable = new HashSet<IConfigurable>();
 | 
			
		||||
            foreach (IConfigurable configurable in configurables)
 | 
			
		||||
            HashSet<IGameConfigurable> modifiable = new HashSet<IGameConfigurable>();
 | 
			
		||||
            foreach (IGameConfigurable configurable in configurables)
 | 
			
		||||
            {
 | 
			
		||||
                modifiable.Add(configurable);
 | 
			
		||||
            }
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using GameServiceWarden.ModuleAPI;
 | 
			
		||||
 | 
			
		||||
namespace GameServiceWarden.Host.Tests.Modules
 | 
			
		||||
namespace GameServiceWarden.Core.Tests.Modules.Games
 | 
			
		||||
{
 | 
			
		||||
    public class FakeGameServiceModule : IGameServiceModule
 | 
			
		||||
    {
 | 
			
		||||
@@ -9,8 +9,8 @@ namespace GameServiceWarden.Host.Tests.Modules
 | 
			
		||||
 | 
			
		||||
        public string Description => "A fake module for testing.";
 | 
			
		||||
 | 
			
		||||
        private IConfigurable[] configurables;
 | 
			
		||||
        public FakeGameServiceModule(params IConfigurable[] configurables)
 | 
			
		||||
        private IGameConfigurable[] configurables;
 | 
			
		||||
        public FakeGameServiceModule(params IGameConfigurable[] configurables)
 | 
			
		||||
        {
 | 
			
		||||
            this.configurables = configurables;
 | 
			
		||||
        }
 | 
			
		||||
@@ -19,7 +19,7 @@ namespace GameServiceWarden.Host.Tests.Modules
 | 
			
		||||
 | 
			
		||||
        public IGameService CreateGameService()
 | 
			
		||||
        {
 | 
			
		||||
            return new FakeService(configurables);
 | 
			
		||||
            return new FakeGameService(configurables);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,24 +1,24 @@
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using GameServiceWarden.Host.Modules;
 | 
			
		||||
using GameServiceWarden.Core.Games;
 | 
			
		||||
using GameServiceWarden.ModuleAPI;
 | 
			
		||||
using Xunit;
 | 
			
		||||
 | 
			
		||||
namespace GameServiceWarden.Host.Tests.Modules
 | 
			
		||||
namespace GameServiceWarden.Core.Tests.Modules.Games
 | 
			
		||||
{
 | 
			
		||||
    // Testing convention from: https://docs.microsoft.com/en-us/dotnet/core/testing/unit-testing-best-practices
 | 
			
		||||
    // Fakes are generic test objects, 
 | 
			
		||||
    // mocks are the objects being asserted upon, 
 | 
			
		||||
    // stubs are objects used as part of the test.
 | 
			
		||||
    public class ServiceInfoTest
 | 
			
		||||
    public class GameServiceInfoTest
 | 
			
		||||
    {
 | 
			
		||||
        //MethodTested_ScenarioTested_ExpectedBehavior
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void Start_FromStopped_StateIsRunning()
 | 
			
		||||
        {
 | 
			
		||||
            //Arrange, Act, Assert
 | 
			
		||||
            IGameService stubGameService = new FakeService();
 | 
			
		||||
            ServiceInfo serviceInfo = new ServiceInfo(stubGameService, "FakeModule", "FakeAssembly");
 | 
			
		||||
            IGameService stubGameService = new FakeGameService();
 | 
			
		||||
            GameServiceInfo serviceInfo = new GameServiceInfo(stubGameService, "FakeModule", "FakeAssembly");
 | 
			
		||||
            serviceInfo.Start();
 | 
			
		||||
            Assert.Equal(ServiceState.Running, serviceInfo.GetServiceState());
 | 
			
		||||
            serviceInfo.Dispose();
 | 
			
		||||
@@ -27,8 +27,8 @@ namespace GameServiceWarden.Host.Tests.Modules
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void Stop_FromStart_Stopped()
 | 
			
		||||
        {
 | 
			
		||||
            IGameService stubService = new FakeService();
 | 
			
		||||
            ServiceInfo serviceInfo = new ServiceInfo(stubService, "FakeModule", "FakeAssembly");
 | 
			
		||||
            IGameService stubService = new FakeGameService();
 | 
			
		||||
            GameServiceInfo serviceInfo = new GameServiceInfo(stubService, "FakeModule", "FakeAssembly");
 | 
			
		||||
            serviceInfo.Start();
 | 
			
		||||
            serviceInfo.Stop();
 | 
			
		||||
            Assert.Equal(ServiceState.Stopped, serviceInfo.GetServiceState());
 | 
			
		||||
@@ -39,12 +39,12 @@ namespace GameServiceWarden.Host.Tests.Modules
 | 
			
		||||
        public void GetConfigurableOptions_ServiceStopped_ReturnsConfigurables()
 | 
			
		||||
        {
 | 
			
		||||
            //Given
 | 
			
		||||
            FakeService stubService = new FakeService();
 | 
			
		||||
            FakeConfigurable stubConfigurable = new FakeConfigurable("Option");
 | 
			
		||||
            HashSet<IConfigurable> configurables = new HashSet<IConfigurable>();
 | 
			
		||||
            FakeGameService stubService = new FakeGameService();
 | 
			
		||||
            FakeGameConfigurable stubConfigurable = new FakeGameConfigurable("Option");
 | 
			
		||||
            HashSet<IGameConfigurable> configurables = new HashSet<IGameConfigurable>();
 | 
			
		||||
            configurables.Add(stubConfigurable);
 | 
			
		||||
            stubService.Configurables = configurables;
 | 
			
		||||
            ServiceInfo serviceInfo = new ServiceInfo(stubService, "FakeModule", "FakeAssembly");
 | 
			
		||||
            GameServiceInfo serviceInfo = new GameServiceInfo(stubService, "FakeModule", "FakeAssembly");
 | 
			
		||||
            //Then
 | 
			
		||||
            Assert.Contains<string>(stubConfigurable.OptionName, serviceInfo.GetConfigurableOptions());
 | 
			
		||||
            serviceInfo.Dispose();
 | 
			
		||||
@@ -54,12 +54,12 @@ namespace GameServiceWarden.Host.Tests.Modules
 | 
			
		||||
        public void SetAndGetConfigurationValue_ServiceStopped_AppropriateValueReturned()
 | 
			
		||||
        {
 | 
			
		||||
            //Given
 | 
			
		||||
            FakeService stubService = new FakeService();
 | 
			
		||||
            FakeConfigurable stubConfigurable = new FakeConfigurable("Option");
 | 
			
		||||
            HashSet<IConfigurable> configurables = new HashSet<IConfigurable>();
 | 
			
		||||
            FakeGameService stubService = new FakeGameService();
 | 
			
		||||
            FakeGameConfigurable stubConfigurable = new FakeGameConfigurable("Option");
 | 
			
		||||
            HashSet<IGameConfigurable> configurables = new HashSet<IGameConfigurable>();
 | 
			
		||||
            configurables.Add(stubConfigurable);
 | 
			
		||||
            stubService.Configurables = configurables;
 | 
			
		||||
            ServiceInfo serviceInfo = new ServiceInfo(stubService, "FakeModule", "FakeAssembly");
 | 
			
		||||
            GameServiceInfo serviceInfo = new GameServiceInfo(stubService, "FakeModule", "FakeAssembly");
 | 
			
		||||
            //When
 | 
			
		||||
            serviceInfo.SetConfigurableValue(stubConfigurable.OptionName, "success");
 | 
			
		||||
            //Then
 | 
			
		||||
@@ -70,8 +70,8 @@ namespace GameServiceWarden.Host.Tests.Modules
 | 
			
		||||
        public void GetServiceState_ServiceNotStarted_ReturnsStoppedState()
 | 
			
		||||
        {
 | 
			
		||||
            //Given
 | 
			
		||||
            IGameService stubService = new FakeService();
 | 
			
		||||
            ServiceInfo serviceInfo = new ServiceInfo(stubService, "FakeModule", "FakeAssembly");
 | 
			
		||||
            IGameService stubService = new FakeGameService();
 | 
			
		||||
            GameServiceInfo serviceInfo = new GameServiceInfo(stubService, "FakeModule", "FakeAssembly");
 | 
			
		||||
            //Then
 | 
			
		||||
            Assert.Equal(ServiceState.Stopped, serviceInfo.GetServiceState());
 | 
			
		||||
            serviceInfo.Dispose();
 | 
			
		||||
@@ -81,8 +81,8 @@ namespace GameServiceWarden.Host.Tests.Modules
 | 
			
		||||
        public void GetServiceState_ServiceStarted_ReturnsRunningState()
 | 
			
		||||
        {
 | 
			
		||||
            //Given
 | 
			
		||||
            IGameService stubService = new FakeService();
 | 
			
		||||
            ServiceInfo serviceInfo = new ServiceInfo(stubService, "FakeModule", "FakeAssembly");
 | 
			
		||||
            IGameService stubService = new FakeGameService();
 | 
			
		||||
            GameServiceInfo serviceInfo = new GameServiceInfo(stubService, "FakeModule", "FakeAssembly");
 | 
			
		||||
            //When
 | 
			
		||||
            serviceInfo.Start();
 | 
			
		||||
            //Then
 | 
			
		||||
@@ -95,8 +95,8 @@ namespace GameServiceWarden.Host.Tests.Modules
 | 
			
		||||
        {
 | 
			
		||||
            //Given
 | 
			
		||||
            const string MODULE_NAME = "FakeModule";
 | 
			
		||||
            IGameService stubService = new FakeService();
 | 
			
		||||
            ServiceInfo serviceInfo = new ServiceInfo(stubService, MODULE_NAME, "FakeAssembly");
 | 
			
		||||
            IGameService stubService = new FakeGameService();
 | 
			
		||||
            GameServiceInfo serviceInfo = new GameServiceInfo(stubService, MODULE_NAME, "FakeAssembly");
 | 
			
		||||
            //Then
 | 
			
		||||
            Assert.Equal(MODULE_NAME, serviceInfo.GetModuleName());
 | 
			
		||||
            serviceInfo.Dispose();
 | 
			
		||||
@@ -107,8 +107,8 @@ namespace GameServiceWarden.Host.Tests.Modules
 | 
			
		||||
        {
 | 
			
		||||
            //Given
 | 
			
		||||
            const string ASSEMBLY_NAME = "FakeAssembly";
 | 
			
		||||
            IGameService stubService = new FakeService();
 | 
			
		||||
            ServiceInfo serviceInfo = new ServiceInfo(stubService, "FakeModule", ASSEMBLY_NAME);
 | 
			
		||||
            IGameService stubService = new FakeGameService();
 | 
			
		||||
            GameServiceInfo serviceInfo = new GameServiceInfo(stubService, "FakeModule", ASSEMBLY_NAME);
 | 
			
		||||
            //Then
 | 
			
		||||
            Assert.Equal(ASSEMBLY_NAME, serviceInfo.GetAssemblyName());
 | 
			
		||||
            serviceInfo.Dispose();
 | 
			
		||||
@@ -119,8 +119,8 @@ namespace GameServiceWarden.Host.Tests.Modules
 | 
			
		||||
        {
 | 
			
		||||
            //Given
 | 
			
		||||
            const string SERVICE_NAME = "Service";
 | 
			
		||||
            IGameService stubService = new FakeService();
 | 
			
		||||
            ServiceInfo serviceInfo = new ServiceInfo(stubService, "FakeModule", "FakeAssemblyName");
 | 
			
		||||
            IGameService stubService = new FakeGameService();
 | 
			
		||||
            GameServiceInfo serviceInfo = new GameServiceInfo(stubService, "FakeModule", "FakeAssemblyName");
 | 
			
		||||
            //When
 | 
			
		||||
            serviceInfo.ServiceName = SERVICE_NAME;
 | 
			
		||||
            //Then
 | 
			
		||||
@@ -132,8 +132,8 @@ namespace GameServiceWarden.Host.Tests.Modules
 | 
			
		||||
        public void ServiceConsoleStream_ServiceNotStarted_NullReturned()
 | 
			
		||||
        {
 | 
			
		||||
            //Given
 | 
			
		||||
            IGameService stubService = new FakeService();
 | 
			
		||||
            ServiceInfo serviceInfo = new ServiceInfo(stubService, "FakeModule", "FakeAssembly");
 | 
			
		||||
            IGameService stubService = new FakeGameService();
 | 
			
		||||
            GameServiceInfo serviceInfo = new GameServiceInfo(stubService, "FakeModule", "FakeAssembly");
 | 
			
		||||
            //Then
 | 
			
		||||
            Assert.Null(serviceInfo.ServiceConsoleStream);
 | 
			
		||||
            serviceInfo.Dispose();
 | 
			
		||||
@@ -143,8 +143,8 @@ namespace GameServiceWarden.Host.Tests.Modules
 | 
			
		||||
        public void ServiceConsoleStream_ServiceStarted_StreamReturned()
 | 
			
		||||
        {
 | 
			
		||||
            //Given
 | 
			
		||||
            IGameService stubService = new FakeService();
 | 
			
		||||
            ServiceInfo serviceInfo = new ServiceInfo(stubService, "FakeModule", "FakeAssembly");
 | 
			
		||||
            IGameService stubService = new FakeGameService();
 | 
			
		||||
            GameServiceInfo serviceInfo = new GameServiceInfo(stubService, "FakeModule", "FakeAssembly");
 | 
			
		||||
            //When
 | 
			
		||||
            serviceInfo.Start();
 | 
			
		||||
            //Then
 | 
			
		||||
@@ -1,18 +1,18 @@
 | 
			
		||||
using System.IO;
 | 
			
		||||
using GameServiceWarden.Host.Modules;
 | 
			
		||||
using GameServiceWarden.Core.Games;
 | 
			
		||||
using GameServiceWarden.ModuleAPI;
 | 
			
		||||
using Xunit;
 | 
			
		||||
 | 
			
		||||
namespace GameServiceWarden.Host.Tests.Modules
 | 
			
		||||
namespace GameServiceWarden.Core.Tests.Modules.Games
 | 
			
		||||
{
 | 
			
		||||
    public class ServiceManagerTest
 | 
			
		||||
    public class GameServiceManagerTest
 | 
			
		||||
    {
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void AddModule_NewManager_SuccessfulAddition()
 | 
			
		||||
        {
 | 
			
		||||
            //Given
 | 
			
		||||
            const string ASSEMBLY_NAME = "FakeAssembly";
 | 
			
		||||
            ServiceManager serviceManager = new ServiceManager();
 | 
			
		||||
            GameServiceManager serviceManager = new GameServiceManager();
 | 
			
		||||
            IGameServiceModule stubGameServiceModule = new FakeGameServiceModule();
 | 
			
		||||
            //When
 | 
			
		||||
            serviceManager.AddModule(ASSEMBLY_NAME, stubGameServiceModule);
 | 
			
		||||
@@ -26,7 +26,7 @@ namespace GameServiceWarden.Host.Tests.Modules
 | 
			
		||||
        {
 | 
			
		||||
            //Given
 | 
			
		||||
            const string ASSEMBLY_NAME = "FakeAssembly";
 | 
			
		||||
            ServiceManager serviceManager = new ServiceManager();
 | 
			
		||||
            GameServiceManager serviceManager = new GameServiceManager();
 | 
			
		||||
            IGameServiceModule stubGameServiceModule = new FakeGameServiceModule();
 | 
			
		||||
            //When
 | 
			
		||||
            serviceManager.AddModule(ASSEMBLY_NAME, stubGameServiceModule);
 | 
			
		||||
@@ -41,7 +41,7 @@ namespace GameServiceWarden.Host.Tests.Modules
 | 
			
		||||
            //Given
 | 
			
		||||
            const string ASSEMBLY_NAME = "FakeAssembly";
 | 
			
		||||
            const string FAKE_SERVICE_NAME = "FakeService";
 | 
			
		||||
            ServiceManager serviceManager = new ServiceManager();
 | 
			
		||||
            GameServiceManager serviceManager = new GameServiceManager();
 | 
			
		||||
            IGameServiceModule stubGameServiceModule = new FakeGameServiceModule();
 | 
			
		||||
            serviceManager.AddModule(ASSEMBLY_NAME, stubGameServiceModule);
 | 
			
		||||
            //When
 | 
			
		||||
@@ -56,7 +56,7 @@ namespace GameServiceWarden.Host.Tests.Modules
 | 
			
		||||
            //Given
 | 
			
		||||
            const string ASSEMBLY_NAME = "FakeAssembly";
 | 
			
		||||
            const string FAKE_SERVICE_NAME = "FakeService";
 | 
			
		||||
            ServiceManager serviceManager = new ServiceManager();
 | 
			
		||||
            GameServiceManager serviceManager = new GameServiceManager();
 | 
			
		||||
            IGameServiceModule stubGameServiceModule = new FakeGameServiceModule();
 | 
			
		||||
            serviceManager.AddModule(ASSEMBLY_NAME, stubGameServiceModule);
 | 
			
		||||
            serviceManager.CreateService(FAKE_SERVICE_NAME, ASSEMBLY_NAME, stubGameServiceModule.Name);
 | 
			
		||||
@@ -72,7 +72,7 @@ namespace GameServiceWarden.Host.Tests.Modules
 | 
			
		||||
            //Given
 | 
			
		||||
            const string ASSEMBLY_NAME = "FakeAssembly";
 | 
			
		||||
            const string FAKE_SERVICE_PREFIX = "FakeService_";
 | 
			
		||||
            ServiceManager serviceManager = new ServiceManager();
 | 
			
		||||
            GameServiceManager serviceManager = new GameServiceManager();
 | 
			
		||||
            IGameServiceModule stubGameServiceModule = new FakeGameServiceModule();
 | 
			
		||||
            //When
 | 
			
		||||
            serviceManager.AddModule(ASSEMBLY_NAME, stubGameServiceModule);
 | 
			
		||||
@@ -93,11 +93,11 @@ namespace GameServiceWarden.Host.Tests.Modules
 | 
			
		||||
            //Given
 | 
			
		||||
            const string ASSEMBLY_NAME = "FakeAssembly";
 | 
			
		||||
            const string SERVICE_NAME = "FakeService";
 | 
			
		||||
            ServiceManager serviceManager = new ServiceManager();
 | 
			
		||||
            GameServiceManager serviceManager = new GameServiceManager();
 | 
			
		||||
            IGameServiceModule stubGameServiceModule = new FakeGameServiceModule(
 | 
			
		||||
                new FakeConfigurable("A"),
 | 
			
		||||
                new FakeConfigurable("B"),
 | 
			
		||||
                new FakeConfigurable("C")
 | 
			
		||||
                new FakeGameConfigurable("A"),
 | 
			
		||||
                new FakeGameConfigurable("B"),
 | 
			
		||||
                new FakeGameConfigurable("C")
 | 
			
		||||
            );
 | 
			
		||||
            //When
 | 
			
		||||
            serviceManager.AddModule(ASSEMBLY_NAME, stubGameServiceModule);
 | 
			
		||||
@@ -114,9 +114,9 @@ namespace GameServiceWarden.Host.Tests.Modules
 | 
			
		||||
            //Given
 | 
			
		||||
            const string ASSEMBLY_NAME = "FakeAssembly";
 | 
			
		||||
            const string SERVICE_NAME = "FakeService";
 | 
			
		||||
            ServiceManager serviceManager = new ServiceManager();
 | 
			
		||||
            GameServiceManager serviceManager = new GameServiceManager();
 | 
			
		||||
            IGameServiceModule stubGameServiceModule = new FakeGameServiceModule(
 | 
			
		||||
                new FakeConfigurable("A")
 | 
			
		||||
                new FakeGameConfigurable("A")
 | 
			
		||||
            );
 | 
			
		||||
            //When
 | 
			
		||||
            serviceManager.AddModule(ASSEMBLY_NAME, stubGameServiceModule);
 | 
			
		||||
@@ -132,7 +132,7 @@ namespace GameServiceWarden.Host.Tests.Modules
 | 
			
		||||
            //Given
 | 
			
		||||
            const string ASSEMBLY_NAME = "FakeAssembly";
 | 
			
		||||
            const string SERVICE_NAME = "FakeService";
 | 
			
		||||
            ServiceManager serviceManager = new ServiceManager();
 | 
			
		||||
            GameServiceManager serviceManager = new GameServiceManager();
 | 
			
		||||
            IGameServiceModule stubGameServiceModule = new FakeGameServiceModule();
 | 
			
		||||
            //When
 | 
			
		||||
            serviceManager.AddModule(ASSEMBLY_NAME, stubGameServiceModule);
 | 
			
		||||
@@ -147,7 +147,7 @@ namespace GameServiceWarden.Host.Tests.Modules
 | 
			
		||||
            //Given
 | 
			
		||||
            const string ASSEMBLY_NAME = "FakeAssembly";
 | 
			
		||||
            const string SERVICE_NAME = "FakeService";
 | 
			
		||||
            ServiceManager serviceManager = new ServiceManager();
 | 
			
		||||
            GameServiceManager serviceManager = new GameServiceManager();
 | 
			
		||||
            IGameServiceModule stubGameServiceModule = new FakeGameServiceModule();
 | 
			
		||||
            //When
 | 
			
		||||
            serviceManager.AddModule(ASSEMBLY_NAME, stubGameServiceModule);
 | 
			
		||||
@@ -163,7 +163,7 @@ namespace GameServiceWarden.Host.Tests.Modules
 | 
			
		||||
            //Given
 | 
			
		||||
            const string ASSEMBLY_NAME = "FakeAssembly";
 | 
			
		||||
            const string SERVICE_NAME = "FakeService";
 | 
			
		||||
            ServiceManager serviceManager = new ServiceManager();
 | 
			
		||||
            GameServiceManager serviceManager = new GameServiceManager();
 | 
			
		||||
            IGameServiceModule stubGameServiceModule = new FakeGameServiceModule();
 | 
			
		||||
            //When
 | 
			
		||||
            serviceManager.AddModule(ASSEMBLY_NAME, stubGameServiceModule);
 | 
			
		||||
@@ -179,7 +179,7 @@ namespace GameServiceWarden.Host.Tests.Modules
 | 
			
		||||
            //Given        
 | 
			
		||||
            const string ASSEMBLY_NAME = "FakeAssembly";
 | 
			
		||||
            const string SERVICE_NAME = "FakeService";
 | 
			
		||||
            ServiceManager serviceManager = new ServiceManager();
 | 
			
		||||
            GameServiceManager serviceManager = new GameServiceManager();
 | 
			
		||||
            IGameServiceModule stubGameServiceModule = new FakeGameServiceModule();
 | 
			
		||||
            //When
 | 
			
		||||
            serviceManager.AddModule(ASSEMBLY_NAME, stubGameServiceModule);
 | 
			
		||||
@@ -196,7 +196,7 @@ namespace GameServiceWarden.Host.Tests.Modules
 | 
			
		||||
            //Given
 | 
			
		||||
            const string ASSEMBLY_NAME = "FakeAssembly";
 | 
			
		||||
            const string SERVICE_NAME = "FakeService";
 | 
			
		||||
            ServiceManager serviceManager = new ServiceManager();
 | 
			
		||||
            GameServiceManager serviceManager = new GameServiceManager();
 | 
			
		||||
            IGameServiceModule stubGameServiceModule = new FakeGameServiceModule();
 | 
			
		||||
            //When
 | 
			
		||||
            serviceManager.AddModule(ASSEMBLY_NAME, stubGameServiceModule);
 | 
			
		||||
@@ -218,7 +218,7 @@ namespace GameServiceWarden.Host.Tests.Modules
 | 
			
		||||
            //Given
 | 
			
		||||
            const string ASSEMBLY_NAME = "FakeAssembly";
 | 
			
		||||
            const string SERVICE_NAME = "FakeService";
 | 
			
		||||
            ServiceManager serviceManager = new ServiceManager();
 | 
			
		||||
            GameServiceManager serviceManager = new GameServiceManager();
 | 
			
		||||
            IGameServiceModule stubGameServiceModule = new FakeGameServiceModule();
 | 
			
		||||
            //When
 | 
			
		||||
            serviceManager.AddModule(ASSEMBLY_NAME, stubGameServiceModule);
 | 
			
		||||
		Reference in New Issue
	
	Block a user