Refactored naming and directory layout of project.

This commit is contained in:
Harrison Deng 2020-12-28 00:43:02 -06:00
parent 334fd37dc6
commit 0cf2335aa7
28 changed files with 324 additions and 183 deletions

4
.vscode/launch.json vendored
View File

@ -10,9 +10,9 @@
"request": "launch", "request": "launch",
"preLaunchTask": "build", "preLaunchTask": "build",
// If you have changed target frameworks, make sure to update the program path. // 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": [], "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 // For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console
"console": "internalConsole", "console": "internalConsole",
"stopAtEntry": false "stopAtEntry": false

6
.vscode/tasks.json vendored
View File

@ -7,7 +7,7 @@
"type": "process", "type": "process",
"args": [ "args": [
"build", "build",
"${workspaceFolder}/src/GameServiceWarden.Host/GameServiceWarden.Host.csproj", "${workspaceFolder}/src/GameServiceWarden.Core/GameServiceWarden.Core.csproj",
"/property:GenerateFullPaths=true", "/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary" "/consoleloggerparameters:NoSummary"
], ],
@ -19,7 +19,7 @@
"type": "process", "type": "process",
"args": [ "args": [
"publish", "publish",
"${workspaceFolder}/src/GameServiceWarden.Host/GameServiceWarden.Host.csproj", "${workspaceFolder}/src/GameServiceWarden.Core/GameServiceWarden.Core.csproj",
"/property:GenerateFullPaths=true", "/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary" "/consoleloggerparameters:NoSummary"
], ],
@ -32,7 +32,7 @@
"args": [ "args": [
"watch", "watch",
"run", "run",
"${workspaceFolder}/src/GameServiceWarden.Host/GameServiceWarden.Host.csproj", "${workspaceFolder}/src/GameServiceWarden.Core/GameServiceWarden.Core.csproj",
"/property:GenerateFullPaths=true", "/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary" "/consoleloggerparameters:NoSummary"
], ],

View File

@ -1,10 +1,10 @@
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; 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 readonly string dataDirectory;
private const string SERVICE_NAME = "Service Name"; 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 MODULE_NAME = "Module Name";
private const string EXTENSION = ".sin"; //Service info private const string EXTENSION = ".sin"; //Service info
public ServiceGateway(string dataDirectory) public GameServiceGateway(string dataDirectory)
{ {
if (!Directory.Exists(dataDirectory)) Directory.CreateDirectory(dataDirectory); if (!Directory.Exists(dataDirectory)) Directory.CreateDirectory(dataDirectory);
this.dataDirectory = dataDirectory; this.dataDirectory = dataDirectory;
@ -53,7 +53,8 @@ namespace GameServiceWarden.Host.Modules
return line.Substring(key.Length + 2); 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}.");
} }

View File

@ -4,12 +4,12 @@ using System.Collections.ObjectModel;
using System.Globalization; using System.Globalization;
using System.IO; using System.IO;
using System.Threading; using System.Threading;
using GameServiceWarden.Host.Preferences; using GameServiceWarden.Core.Preferences;
using GameServiceWarden.ModuleAPI; using GameServiceWarden.ModuleAPI;
namespace GameServiceWarden.Host.Modules namespace GameServiceWarden.Core.Games
{ {
public class ServiceInfo : IDisposable //entity public class GameServiceInfo : IDisposable //entity
{ {
/// <summary> /// <summary>
@ -27,22 +27,22 @@ namespace GameServiceWarden.Host.Modules
private readonly IGameService service; private readonly IGameService service;
private readonly string assemblyName; private readonly string assemblyName;
private readonly string moduleName; private readonly string moduleName;
private readonly IReadOnlyDictionary<string, IConfigurable> configurables; private readonly IReadOnlyDictionary<string, IGameConfigurable> configurables;
private bool disposed; 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.service = service ?? throw new ArgumentNullException("service");
this.moduleName = moduleName ?? throw new ArgumentNullException("moduleName"); this.moduleName = moduleName ?? throw new ArgumentNullException("moduleName");
this.assemblyName = assemblyName ?? throw new ArgumentNullException("assemblyName"); this.assemblyName = assemblyName ?? throw new ArgumentNullException("assemblyName");
this.service.StateChangeEvent += OnServiceStateChange; this.service.StateChangeEvent += OnServiceStateChange;
Dictionary<string, IConfigurable> configurables = new Dictionary<string, IConfigurable>(); Dictionary<string, IGameConfigurable> configurables = new Dictionary<string, IGameConfigurable>();
foreach (IConfigurable configurable in service.Configurables) foreach (IGameConfigurable configurable in service.Configurables)
{ {
configurables.Add(configurable.OptionName, configurable); configurables.Add(configurable.OptionName, configurable);
} }
this.configurables = new ReadOnlyDictionary<string, IConfigurable>(configurables); this.configurables = new ReadOnlyDictionary<string, IGameConfigurable>(configurables);
} }
/// <summary> /// <summary>
@ -93,7 +93,7 @@ namespace GameServiceWarden.Host.Modules
} }
/// <summary> /// <summary>
/// Gets the possible <see cref="IConfigurable"/>'s names for this service. /// Gets the possible <see cref="IGameConfigurable"/>'s names for this service.
/// </summary> /// </summary>
/// <returns>A <see cref="ISet{string}"/> returned where the string is the option's name.</returns> /// <returns>A <see cref="ISet{string}"/> returned where the string is the option's name.</returns>
public ISet<string> GetConfigurableOptions() public ISet<string> GetConfigurableOptions()

View File

@ -3,11 +3,11 @@ using System.Collections.Generic;
using System.IO; using System.IO;
using GameServiceWarden.ModuleAPI; 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>>(); private readonly Dictionary<string, Dictionary<string, IGameServiceModule>> modules = new Dictionary<string, Dictionary<string, IGameServiceModule>>();
public void AddModule(string assemblyName, IGameServiceModule module) 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 (!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."); 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) public void DeleteService(string serviceName)
@ -64,7 +64,7 @@ namespace GameServiceWarden.Host.Modules
public IEnumerable<string> GetServiceOptions(string serviceName) public IEnumerable<string> GetServiceOptions(string serviceName)
{ {
if (!services.ContainsKey(serviceName)) throw new KeyNotFoundException($"Service under name \"{serviceName}\" not found."); if (!services.ContainsKey(serviceName)) throw new KeyNotFoundException($"Service under name \"{serviceName}\" not found.");
ServiceInfo serviceInfo = services[serviceName]; GameServiceInfo serviceInfo = services[serviceName];
return serviceInfo.GetConfigurableOptions(); return serviceInfo.GetConfigurableOptions();
} }

View File

@ -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) { }
}
}

View File

@ -2,13 +2,13 @@ using System;
using System.Reflection; using System.Reflection;
using System.Runtime.Loader; using System.Runtime.Loader;
namespace GameServiceWarden.Host.Modules namespace GameServiceWarden.Core.Games.Modules
{ {
class ModuleLoadContext : AssemblyLoadContext class GameModuleLoadContext : AssemblyLoadContext
{ {
private readonly AssemblyDependencyResolver dependencyResolver; private readonly AssemblyDependencyResolver dependencyResolver;
public ModuleLoadContext(string path) { public GameModuleLoadContext(string path) {
dependencyResolver = new AssemblyDependencyResolver(path); dependencyResolver = new AssemblyDependencyResolver(path);
} }

View File

@ -1,12 +1,12 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Reflection; using System.Reflection;
using GameServiceWarden.Host.Modules.Exceptions; using GameServiceWarden.Core.Games.Modules.Exceptions;
using GameServiceWarden.ModuleAPI; using GameServiceWarden.ModuleAPI;
namespace GameServiceWarden.Host.Modules namespace GameServiceWarden.Core.Games.Modules
{ {
public class ModuleLoader //Gateway public class GameModuleLoader //Gateway
{ {
/// <summary> /// <summary>
/// Loads an extension module. /// Loads an extension module.
@ -36,7 +36,7 @@ namespace GameServiceWarden.Host.Modules
private Assembly loadAssembly(string path) private Assembly loadAssembly(string path)
{ {
ModuleLoadContext moduleLoadContext = new ModuleLoadContext(path); GameModuleLoadContext moduleLoadContext = new GameModuleLoadContext(path);
return moduleLoadContext.LoadFromAssemblyPath(path); return moduleLoadContext.LoadFromAssemblyPath(path);
} }
@ -65,7 +65,7 @@ namespace GameServiceWarden.Host.Modules
} }
string types = String.Join(',', typeNames); string types = String.Join(',', typeNames);
throw new NoServiceableFoundException( throw new ModuleLoadException(
$"No public classes in {assembly} from {assembly.Location} implemented {typeof(IGameService).FullName}." + $"No public classes in {assembly} from {assembly.Location} implemented {typeof(IGameService).FullName}." +
$"Detected types: {types}"); $"Detected types: {types}");
} }

View File

@ -1,6 +1,6 @@
using System; using System;
namespace GameServiceWarden.Host.Logging namespace GameServiceWarden.Core.Logging
{ {
public class FileLogReceiver : ILogReceiver public class FileLogReceiver : ILogReceiver
{ {

View File

@ -1,6 +1,6 @@
using System; using System;
namespace GameServiceWarden.Host.Logging namespace GameServiceWarden.Core.Logging
{ {
public interface ILogReceiver public interface ILogReceiver
{ {

View File

@ -1,4 +1,4 @@
namespace GameServiceWarden.Host.Logging namespace GameServiceWarden.Core.Logging
{ {
public enum LogLevel public enum LogLevel
{ {

View File

@ -1,7 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
namespace GameServiceWarden.Host.Logging namespace GameServiceWarden.Core.Logging
{ {
public class Logger { public class Logger {
private readonly HashSet<ILogReceiver> listeners = new HashSet<ILogReceiver>(); private readonly HashSet<ILogReceiver> listeners = new HashSet<ILogReceiver>();

View File

@ -4,7 +4,7 @@ using System.Net;
using System.Reflection; using System.Reflection;
using System.Xml.Serialization; using System.Xml.Serialization;
namespace GameServiceWarden.Host.Preferences namespace GameServiceWarden.Core.Preferences
{ {
[Serializable] [Serializable]
public class GeneralPreferences : IPersistable public class GeneralPreferences : IPersistable

View File

@ -1,4 +1,4 @@
namespace GameServiceWarden.Host.Preferences namespace GameServiceWarden.Core.Preferences
{ {
public interface IPersistable public interface IPersistable
{ {

View File

@ -1,6 +1,6 @@
using System; using System;
namespace GameServiceWarden.Host namespace GameServiceWarden.Core
{ {
class Program class Program
{ {

View File

@ -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"> <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> <root>
<mxCell id="0"/> <mxCell id="0"/>
<mxCell id="1" parent="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"> <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"/> <mxGeometry relative="1" as="geometry"/>
</mxCell> </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"/> <mxGeometry x="762" y="1030" width="401" height="400" as="geometry"/>
</mxCell> </mxCell>
<mxCell id="dmd0HlDYcxYugIlahWj0-6" value="- serviceName: string&#10;- controlLock: object&#10;- state: ServiceState&#10;- service: IGameService&#10;- serviceConsoleStream: Stream&#10;- moduleName: string&#10;- assemblyName: string&#10;- Dictionary&lt;string, IConfigurable&gt;&#10;- 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"> <mxCell id="dmd0HlDYcxYugIlahWj0-6" value="- serviceName: string&#10;- controlLock: object&#10;- state: ServiceState&#10;- service: IGameService&#10;- serviceConsoleStream: Stream&#10;- moduleName: string&#10;- assemblyName: string&#10;- Dictionary&lt;string, IConfigurable&gt;&#10;- 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"> <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"/> <mxGeometry relative="1" as="geometry"/>
</mxCell> </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"> <mxGeometry x="722" y="670" width="481" height="280" as="geometry">
<mxRectangle x="25" y="490" width="120" height="26" as="alternateBounds"/> <mxRectangle x="25" y="490" width="120" height="26" as="alternateBounds"/>
</mxGeometry> </mxGeometry>
@ -54,7 +54,7 @@
<mxCell id="dmd0HlDYcxYugIlahWj0-14" value="+ AddModule(assemblyName: string, module: IGameServiceModule): void&#10;+ RemoveModule(assemblyName: string, moduleName string): void&#10;+ CreateService(serviceName: string, assemblyName: string, moduleName: string): void&#10;+ DeleteService(serviceName: string): void&#10;+ GetServiceNames(): IReadOnlyCollection&lt;string&gt;&#10;+ GetServiceOptionsValue(serviceName: string): IEnumerable&lt;string&gt;&#10;+ SetServiceOptionValue(serviceName: string, optionName: string, string: value): bool&#10;+ GetServiceState(serviceName: string): ServiceState&#10;+ StartService(serviceName: string): void&#10;+ StopService(serviceName: string): void&#10;+ ExecuteCommand(serviceName: string, command: string): void&#10;+ GetServiceConsoleStream(): Stream&#10;+ 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"> <mxCell id="dmd0HlDYcxYugIlahWj0-14" value="+ AddModule(assemblyName: string, module: IGameServiceModule): void&#10;+ RemoveModule(assemblyName: string, moduleName string): void&#10;+ CreateService(serviceName: string, assemblyName: string, moduleName: string): void&#10;+ DeleteService(serviceName: string): void&#10;+ GetServiceNames(): IReadOnlyCollection&lt;string&gt;&#10;+ GetServiceOptionsValue(serviceName: string): IEnumerable&lt;string&gt;&#10;+ SetServiceOptionValue(serviceName: string, optionName: string, string: value): bool&#10;+ GetServiceState(serviceName: string): ServiceState&#10;+ StartService(serviceName: string): void&#10;+ StopService(serviceName: string): void&#10;+ ExecuteCommand(serviceName: string, command: string): void&#10;+ GetServiceConsoleStream(): Stream&#10;+ 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"/> <mxGeometry y="78" width="481" height="202" as="geometry"/>
</mxCell> </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"/> <mxGeometry x="1700" y="490" width="460" height="140" as="geometry"/>
</mxCell> </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"> <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&#10;- LoadAssembly(path: string): void&#10;+ LoadModules(path: string): IEnumerable&lt;IGameServiceModule&gt;&#10;+ LoadAllModules(path: string[]): IEnumerable&lt;IGameServiceModule&gt;&#10;+ LoadAllModules(path: IEnumerable&lt;string&gt;): IEnumerable&lt;IGameServiceModule&gt;" 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"> <mxCell id="dmd0HlDYcxYugIlahWj0-19" value="- InstantiateServiceables(assembly: Assembly): void&#10;- LoadAssembly(path: string): void&#10;+ LoadModules(path: string): IEnumerable&lt;IGameServiceModule&gt;&#10;+ LoadAllModules(path: string[]): IEnumerable&lt;IGameServiceModule&gt;&#10;+ LoadAllModules(path: IEnumerable&lt;string&gt;): IEnumerable&lt;IGameServiceModule&gt;" 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"/> <mxGeometry y="60" width="460" height="80" as="geometry"/>
</mxCell> </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"> <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="2590" y="490" width="440" height="130" as="geometry"/> <mxGeometry x="2190" y="490" width="440" height="130" as="geometry"/>
</mxCell> </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"> <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"/> <mxGeometry y="26" width="440" height="26" as="geometry"/>
@ -79,7 +79,7 @@
<mxGeometry y="60" width="440" height="70" as="geometry"/> <mxGeometry y="60" width="440" height="70" as="geometry"/>
</mxCell> </mxCell>
<mxCell id="dmd0HlDYcxYugIlahWj0-38" value="&lt;&lt;Interface&gt;&gt;&#10;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"> <mxCell id="dmd0HlDYcxYugIlahWj0-38" value="&lt;&lt;Interface&gt;&gt;&#10;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>
<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"> <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"/> <mxGeometry y="40" width="181" height="8" as="geometry"/>
@ -88,7 +88,7 @@
<mxGeometry y="48" width="181" height="66" as="geometry"/> <mxGeometry y="48" width="181" height="66" as="geometry"/>
</mxCell> </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"> <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>
<mxCell id="2br9O0FZKGLhbr8u3XJU-2" value="- mainController: ITextCommand&#10;- 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"> <mxCell id="2br9O0FZKGLhbr8u3XJU-2" value="- mainController: ITextCommand&#10;- 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"/> <mxGeometry y="26" width="200" height="44" as="geometry"/>
@ -104,11 +104,11 @@
</mxCell> </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"> <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"> <mxGeometry relative="1" as="geometry">
<mxPoint x="950" y="82" as="targetPoint"/> <mxPoint x="950" y="162" as="targetPoint"/>
</mxGeometry> </mxGeometry>
</mxCell> </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"> <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>
<mxCell id="qpeZJq-dxPH0P0VpmRa_-8" value="+ commands: Dictionary&lt;string, ITextCommand&gt;" 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"> <mxCell id="qpeZJq-dxPH0P0VpmRa_-8" value="+ commands: Dictionary&lt;string, ITextCommand&gt;" 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"/> <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"> <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"/> <mxGeometry relative="1" as="geometry"/>
</mxCell> </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"> <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="240" width="241" height="60" as="geometry"/> <mxGeometry x="1255" y="320" width="241" height="60" as="geometry"/>
</mxCell> </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"> <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"/> <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"> <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"/> <mxGeometry relative="1" as="geometry"/>
</mxCell> </mxCell>
<mxCell id="wwlaSBDwwZOn0hO83bWU-2" value="&lt;&lt;Interface&gt;&gt;&#10;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"> <mxCell id="wwlaSBDwwZOn0hO83bWU-2" value="&lt;&lt;Interface&gt;&gt;&#10;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="350" width="201" height="74" as="geometry"/> <mxGeometry x="1275" y="480" width="201" height="74" as="geometry"/>
</mxCell> </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"> <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"/> <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"> <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"/> <mxGeometry relative="1" as="geometry"/>
</mxCell> </mxCell>
<mxCell id="wwlaSBDwwZOn0hO83bWU-12" value="&lt;&lt;DS&gt;&gt;&#10;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"> <mxCell id="wwlaSBDwwZOn0hO83bWU-12" value="&lt;&lt;DS&gt;&gt;&#10;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="1400" y="464" width="161" height="144" as="geometry"/> <mxGeometry x="1466" y="600" width="161" height="128" as="geometry"/>
</mxCell> </mxCell>
<mxCell id="wwlaSBDwwZOn0hO83bWU-13" value="+ assemblyName: string&#10;+ moduleName: string&#10;+ serviceName: string&#10;" 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"> <mxCell id="wwlaSBDwwZOn0hO83bWU-13" value="+ AssemblyName: string&#10;+ ModuleName: string&#10;+ ServiceName: string&#10;+ Module: IModule&#10;+ 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="70" as="geometry"/> <mxGeometry y="40" width="161" height="80" as="geometry"/>
</mxCell> </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"> <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"/> <mxGeometry y="120" 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"/>
</mxCell> </mxCell>
<mxCell id="wwlaSBDwwZOn0hO83bWU-19" value="&lt;&lt;Interface&gt;&gt;&#10;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"> <mxCell id="wwlaSBDwwZOn0hO83bWU-19" value="&lt;&lt;Interface&gt;&gt;&#10;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>
<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"> <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"/> <mxGeometry y="40" width="310" height="8" as="geometry"/>
@ -180,7 +177,7 @@
<mxGeometry relative="1" as="geometry"/> <mxGeometry relative="1" as="geometry"/>
</mxCell> </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"> <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>
<mxCell id="HUSvFZX5SimreebZp30a-6" value="- textPresenters: Dictionary&lt;string, ITextOutput&gt;" 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"> <mxCell id="HUSvFZX5SimreebZp30a-6" value="- textPresenters: Dictionary&lt;string, ITextOutput&gt;" 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"/> <mxGeometry y="26" width="270" height="26" as="geometry"/>
@ -195,7 +192,7 @@
<mxGeometry relative="1" as="geometry"/> <mxGeometry relative="1" as="geometry"/>
</mxCell> </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"> <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>
<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"> <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"/> <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"> <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"/> <mxGeometry relative="1" as="geometry"/>
</mxCell> </mxCell>
<mxCell id="zFFzFwxISwJASp9ezwbr-1" value="&lt;&lt;Interface&gt;&gt;&#10;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"> <mxCell id="zFFzFwxISwJASp9ezwbr-1" value="&lt;&lt;Interface&gt;&gt;&#10;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="360" width="280" height="74" as="geometry"/> <mxGeometry x="355" y="464" width="280" height="74" as="geometry"/>
</mxCell> </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"> <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"/> <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"> <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"/> <mxGeometry y="48" width="280" height="26" as="geometry"/>
</mxCell> </mxCell>
<mxCell id="fdKXkHfjRXYybK0fejAG-9" value="&lt;&lt;DS&gt;&gt;&#10;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"> <mxCell id="fdKXkHfjRXYybK0fejAG-9" value="&lt;&lt;DS&gt;&gt;&#10;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="320" y="860" width="350" height="138" as="geometry"/> <mxGeometry x="225" y="830" width="365" height="138" as="geometry"/>
</mxCell> </mxCell>
<mxCell id="fdKXkHfjRXYybK0fejAG-10" value="+ Services: ICollection&lt;string&gt;&#10;+ Running: ICollection&lt;string&gt;&#10;+ Errors: ICollection&lt;string&gt;&#10;+ Consoles: IDictionary&lt;string, Stream&gt;&#10;+ ServiceOptions: IDictionary&lt;string, IDictionary&lt;string, string&gt;&gt;" 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"> <mxCell id="fdKXkHfjRXYybK0fejAG-10" value="+ Services: ICollection&lt;string&gt;&#10;+ Running: ICollection&lt;string&gt;&#10;+ Errors: ICollection&lt;string&gt;&#10;+ Consoles: IDictionary&lt;string, Stream&gt;&#10;+ ServiceOptions: IDictionary&lt;string, IDictionary&lt;string, string&gt;&gt;" 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>
<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"> <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>
<mxCell id="SI3d9EEbteElKQB4Ic5T-10" value="&lt;&lt;Enum&gt;&gt;&#10;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"> <mxCell id="SI3d9EEbteElKQB4Ic5T-10" value="&lt;&lt;Enum&gt;&gt;&#10;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="442" width="160" height="188" as="geometry"/> <mxGeometry x="882.5" y="420" width="160" height="188" as="geometry"/>
</mxCell> </mxCell>
<mxCell id="SI3d9EEbteElKQB4Ic5T-11" value="+ Start&#10;+ Stop&#10;+ AddModule&#10;+ RemoveModule&#10;+ CreateService&#10;+ DeleteService&#10;+ Execute&#10;+ SetServiceOption&#10;+ 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"> <mxCell id="SI3d9EEbteElKQB4Ic5T-11" value="+ Start&#10;+ Stop&#10;+ AddModule&#10;+ RemoveModule&#10;+ CreateService&#10;+ DeleteService&#10;+ Execute&#10;+ SetServiceOption&#10;+ 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"/> <mxGeometry y="40" width="160" height="140" as="geometry"/>
@ -234,176 +231,348 @@
</mxGraphModel> </mxGraphModel>
</diagram> </diagram>
<diagram id="gj0qHRc3eh050ABAey3g" name="Data-Flow"> <diagram id="gj0qHRc3eh050ABAey3g" name="Data-Flow">
&#xa; &#xa;&#xa;
<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="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">
&#xa; &#xa;&#xa;
<root> <root>
&#xa; &#xa;&#xa;
<mxCell id="jVG6p58vlRYGO9X4wXeX-0"/> <mxCell id="jVG6p58vlRYGO9X4wXeX-0"/>
&#xa; &#xa;&#xa;
<mxCell id="jVG6p58vlRYGO9X4wXeX-1" parent="jVG6p58vlRYGO9X4wXeX-0"/> <mxCell id="jVG6p58vlRYGO9X4wXeX-1" parent="jVG6p58vlRYGO9X4wXeX-0"/>
&#xa; &#xa;&#xa;
<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"> <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">
&#xa; &#xa;&#xa;
<mxGeometry relative="1" as="geometry"/> <mxGeometry relative="1" as="geometry"/>
&#xa; &#xa;&#xa;
</mxCell> </mxCell>
&#xa; &#xa;&#xa;
<mxCell id="jVG6p58vlRYGO9X4wXeX-2" value="Actor" style="shape=umlActor;verticalLabelPosition=bottom;verticalAlign=top;html=1;outlineConnect=0;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1"> <mxCell id="jVG6p58vlRYGO9X4wXeX-2" value="Actor" style="shape=umlActor;verticalLabelPosition=bottom;verticalAlign=top;html=1;outlineConnect=0;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
&#xa; &#xa;&#xa;
<mxGeometry x="10" y="300" width="30" height="60" as="geometry"/> <mxGeometry x="10" y="300" width="30" height="60" as="geometry"/>
&#xa; &#xa;&#xa;
</mxCell> </mxCell>
&#xa; &#xa;&#xa;
<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"> <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">
&#xa; &#xa;&#xa;
<mxGeometry relative="1" as="geometry"/> <mxGeometry relative="1" as="geometry"/>
&#xa; &#xa;&#xa;
</mxCell> </mxCell>
&#xa; &#xa;&#xa;
<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"> <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">
&#xa; &#xa;&#xa;
<mxGeometry relative="1" as="geometry"/> <mxGeometry relative="1" as="geometry"/>
&#xa; &#xa;&#xa;
</mxCell> </mxCell>
&#xa; &#xa;&#xa;
<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"> <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">
&#xa; &#xa;&#xa;
<mxGeometry relative="1" as="geometry"/> <mxGeometry relative="1" as="geometry"/>
&#xa; &#xa;&#xa;
</mxCell> </mxCell>
&#xa; &#xa;&#xa;
<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"> <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">
&#xa; &#xa;&#xa;
<mxGeometry relative="1" as="geometry"/> <mxGeometry relative="1" as="geometry"/>
&#xa; &#xa;&#xa;
</mxCell> </mxCell>
&#xa; &#xa;&#xa;
<mxCell id="jVG6p58vlRYGO9X4wXeX-3" value="Console View" style="rounded=0;whiteSpace=wrap;html=1;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1"> <mxCell id="jVG6p58vlRYGO9X4wXeX-3" value="Console View" style="rounded=0;whiteSpace=wrap;html=1;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
&#xa; &#xa;&#xa;
<mxGeometry x="80" y="300" width="120" height="60" as="geometry"/> <mxGeometry x="80" y="300" width="120" height="60" as="geometry"/>
&#xa; &#xa;&#xa;
</mxCell> </mxCell>
&#xa; &#xa;&#xa;
<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"> <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">
&#xa; &#xa;&#xa;
<mxGeometry relative="1" as="geometry"/> <mxGeometry relative="1" as="geometry"/>
&#xa; &#xa;&#xa;
</mxCell> </mxCell>
&#xa; &#xa;&#xa;
<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"> <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">
&#xa; &#xa;&#xa;
<mxGeometry relative="1" as="geometry"/> <mxGeometry relative="1" as="geometry"/>
&#xa; &#xa;&#xa;
</mxCell> </mxCell>
&#xa; &#xa;&#xa;
<mxCell id="jVG6p58vlRYGO9X4wXeX-4" value="string command (request)" style="rounded=0;whiteSpace=wrap;html=1;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1"> <mxCell id="jVG6p58vlRYGO9X4wXeX-4" value="string command (request)" style="rounded=0;whiteSpace=wrap;html=1;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
&#xa; &#xa;&#xa;
<mxGeometry x="260" y="482.5" width="120" height="60" as="geometry"/> <mxGeometry x="260" y="482.5" width="120" height="60" as="geometry"/>
&#xa; &#xa;&#xa;
</mxCell> </mxCell>
&#xa; &#xa;&#xa;
<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"> <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">
&#xa; &#xa;&#xa;
<mxGeometry relative="1" as="geometry"/> <mxGeometry relative="1" as="geometry"/>
&#xa; &#xa;&#xa;
</mxCell> </mxCell>
&#xa; &#xa;&#xa;
<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"> <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">
&#xa; &#xa;&#xa;
<mxGeometry relative="1" as="geometry"/> <mxGeometry relative="1" as="geometry"/>
&#xa; &#xa;&#xa;
</mxCell> </mxCell>
&#xa; &#xa;&#xa;
<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"> <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">
&#xa; &#xa;&#xa;
<mxGeometry relative="1" as="geometry"/> <mxGeometry relative="1" as="geometry"/>
&#xa; &#xa;&#xa;
</mxCell> </mxCell>
&#xa; &#xa;&#xa;
<mxCell id="jVG6p58vlRYGO9X4wXeX-5" value="MainController" style="rounded=0;whiteSpace=wrap;html=1;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1"> <mxCell id="jVG6p58vlRYGO9X4wXeX-5" value="MainController" style="rounded=0;whiteSpace=wrap;html=1;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
&#xa; &#xa;&#xa;
<mxGeometry x="420" y="482.5" width="120" height="60" as="geometry"/> <mxGeometry x="420" y="482.5" width="120" height="60" as="geometry"/>
&#xa; &#xa;&#xa;
</mxCell> </mxCell>
&#xa; &#xa;&#xa;
<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"> <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">
&#xa; &#xa;&#xa;
<mxGeometry y="840" width="480" height="20" as="geometry"/> <mxGeometry y="840" width="480" height="20" as="geometry"/>
&#xa; &#xa;&#xa;
</mxCell> </mxCell>
&#xa; &#xa;&#xa;
<mxCell id="jVG6p58vlRYGO9X4wXeX-7" value="&amp;lt;&amp;lt;Interface&amp;gt;&amp;gt;&lt;br&gt;ICommand" style="rounded=0;whiteSpace=wrap;html=1;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1"> <mxCell id="jVG6p58vlRYGO9X4wXeX-7" value="&amp;lt;&amp;lt;Interface&amp;gt;&amp;gt;&lt;br&gt;ICommand" style="rounded=0;whiteSpace=wrap;html=1;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
&#xa; &#xa;&#xa;
<mxGeometry x="420" y="372.5" width="120" height="60" as="geometry"/> <mxGeometry x="420" y="372.5" width="120" height="60" as="geometry"/>
&#xa; &#xa;&#xa;
</mxCell> </mxCell>
&#xa; &#xa;&#xa;
<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"> <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">
&#xa; &#xa;&#xa;
<mxGeometry relative="1" as="geometry"/> <mxGeometry relative="1" as="geometry"/>
&#xa; &#xa;&#xa;
</mxCell> </mxCell>
&#xa; &#xa;&#xa;
<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"> <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">
&#xa; &#xa;&#xa;
<mxGeometry relative="1" as="geometry"> <mxGeometry relative="1" as="geometry">
&#xa; &#xa;&#xa;
<mxPoint x="809.9999999999998" y="512.5000000000002" as="sourcePoint"/> <mxPoint x="809.9999999999998" y="512.5000000000002" as="sourcePoint"/>
&#xa; &#xa;&#xa;
</mxGeometry> </mxGeometry>
&#xa; &#xa;&#xa;
</mxCell> </mxCell>
&#xa; &#xa;&#xa;
<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"> <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">
&#xa; &#xa;&#xa;
<mxGeometry relative="1" as="geometry"/> <mxGeometry relative="1" as="geometry"/>
&#xa; &#xa;&#xa;
</mxCell> </mxCell>
&#xa; &#xa;&#xa;
<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"> <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">
&#xa; &#xa;&#xa;
<mxGeometry relative="1" as="geometry"/> <mxGeometry relative="1" as="geometry"/>
&#xa; &#xa;&#xa;
</mxCell> </mxCell>
&#xa; &#xa;&#xa;
<mxCell id="jVG6p58vlRYGO9X4wXeX-9" value="ServiceController" style="rounded=0;whiteSpace=wrap;html=1;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1"> <mxCell id="jVG6p58vlRYGO9X4wXeX-9" value="ServiceController" style="rounded=0;whiteSpace=wrap;html=1;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
&#xa; &#xa;&#xa;
<mxGeometry x="575" y="482.5" width="120" height="60" as="geometry"/> <mxGeometry x="575" y="482.5" width="120" height="60" as="geometry"/>
&#xa; &#xa;&#xa;
</mxCell> </mxCell>
&#xa; &#xa;&#xa;
<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"> <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">
&#xa; &#xa;&#xa;
<mxGeometry relative="1" as="geometry"/> <mxGeometry relative="1" as="geometry"/>
&#xa; &#xa;&#xa;
</mxCell> </mxCell>
&#xa; &#xa;&#xa;
<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"> <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">
&#xa; &#xa;&#xa;
<mxGeometry relative="1" as="geometry"/> <mxGeometry relative="1" as="geometry"/>
&#xa; &#xa;&#xa;
</mxCell> </mxCell>
&#xa; &#xa;&#xa;
<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"> <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">
&#xa; &#xa;&#xa;
<mxGeometry relative="1" as="geometry"> <mxGeometry relative="1" as="geometry">
&#xa; &#xa;&#xa;
<Array as="points"> <Array as="points">
&#xa; &#xa;&#xa;
<mxPoint x="960" y="338"/> <mxPoint x="960" y="338"/>
&#xa; &#xa;&#xa;
<mxPoint x="960" y="580"/> <mxPoint x="960" y="580"/>
&#xa; &#xa;&#xa;
</Array> </Array>
&#xa; &#xa;&#xa;
</mxGeometry> </mxGeometry>
&#xa; &#xa;&#xa;
</mxCell> </mxCell>
&#xa; &#xa;&#xa;
<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"> <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">
&#xa; &#xa;&#xa;
<mxGeometry relative="1" as="geometry"/> <mxGeometry relative="1" as="geometry"/>
&#xa; &#xa;&#xa;
</mxCell> </mxCell>
&#xa; &#xa;&#xa;
<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"> <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">
&#xa; &#xa;&#xa;
<mxGeometry relative="1" as="geometry"> <mxGeometry relative="1" as="geometry">
&#xa; &#xa;&#xa;
<Array as="points"> <Array as="points">
&#xa; &#xa;&#xa;
<mxPoint x="960" y="338"/> <mxPoint x="960" y="338"/>
&#xa; &#xa;&#xa;
<mxPoint x="960" y="83"/> <mxPoint x="960" y="83"/>
&#xa; &#xa;&#xa;
</Array> </Array>
&#xa; &#xa;&#xa;
</mxGeometry> </mxGeometry>
&#xa; &#xa;&#xa;
</mxCell> </mxCell>
&#xa; &#xa;&#xa;
<mxCell id="28FAlPysTx9DMYvLwa-2-1" value="ServiceManager" style="rounded=0;whiteSpace=wrap;html=1;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1"> <mxCell id="28FAlPysTx9DMYvLwa-2-1" value="ServiceManager" style="rounded=0;whiteSpace=wrap;html=1;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
&#xa; &#xa;&#xa;
<mxGeometry x="800" y="307.5" width="120" height="60" as="geometry"/> <mxGeometry x="800" y="307.5" width="120" height="60" as="geometry"/>
&#xa; &#xa;&#xa;
</mxCell> </mxCell>
&#xa; &#xa;&#xa;
<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"> <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">
&#xa; &#xa;&#xa;
<mxGeometry relative="1" as="geometry"/> <mxGeometry relative="1" as="geometry"/>
&#xa; &#xa;&#xa;
</mxCell> </mxCell>
&#xa; &#xa;&#xa;
<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"> <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">
&#xa; &#xa;&#xa;
<mxGeometry relative="1" as="geometry"/> <mxGeometry relative="1" as="geometry"/>
&#xa; &#xa;&#xa;
</mxCell> </mxCell>
&#xa; &#xa;&#xa;
<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"> <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">
&#xa; &#xa;&#xa;
<mxGeometry relative="1" as="geometry"/> <mxGeometry relative="1" as="geometry"/>
&#xa; &#xa;&#xa;
</mxCell> </mxCell>
&#xa; &#xa;&#xa;
<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"> <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">
&#xa; &#xa;&#xa;
<mxGeometry relative="1" as="geometry"/> <mxGeometry relative="1" as="geometry"/>
&#xa; &#xa;&#xa;
</mxCell> </mxCell>
&#xa; &#xa;&#xa;
<mxCell id="28FAlPysTx9DMYvLwa-2-5" value="ServicePresenter" style="rounded=0;whiteSpace=wrap;html=1;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1"> <mxCell id="28FAlPysTx9DMYvLwa-2-5" value="ServicePresenter" style="rounded=0;whiteSpace=wrap;html=1;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
&#xa; &#xa;&#xa;
<mxGeometry x="575" y="122.5" width="120" height="60" as="geometry"/> <mxGeometry x="575" y="122.5" width="120" height="60" as="geometry"/>
&#xa; &#xa;&#xa;
</mxCell> </mxCell>
&#xa; &#xa;&#xa;
<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"> <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">
&#xa; &#xa;&#xa;
<mxGeometry relative="1" as="geometry"/> <mxGeometry relative="1" as="geometry"/>
&#xa; &#xa;&#xa;
</mxCell> </mxCell>
&#xa; &#xa;&#xa;
<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"> <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">
&#xa; &#xa;&#xa;
<mxGeometry relative="1" as="geometry"/> <mxGeometry relative="1" as="geometry"/>
&#xa; &#xa;&#xa;
</mxCell> </mxCell>
&#xa; &#xa;&#xa;
<mxCell id="28FAlPysTx9DMYvLwa-2-7" value="String Output" style="rounded=0;whiteSpace=wrap;html=1;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1"> <mxCell id="28FAlPysTx9DMYvLwa-2-7" value="String Output" style="rounded=0;whiteSpace=wrap;html=1;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
&#xa; &#xa;&#xa;
<mxGeometry x="260" y="122.5" width="120" height="60" as="geometry"/> <mxGeometry x="260" y="122.5" width="120" height="60" as="geometry"/>
&#xa; &#xa;&#xa;
</mxCell> </mxCell>
&#xa; &#xa;&#xa;
<mxCell id="UY-EM7-1ECCvWtENr50b-1" value="ServiceAction &amp;lt;DS&amp;gt;" style="rounded=0;whiteSpace=wrap;html=1;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1"> <mxCell id="UY-EM7-1ECCvWtENr50b-1" value="ServiceAction &amp;lt;DS&amp;gt;" style="rounded=0;whiteSpace=wrap;html=1;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
&#xa; &#xa;&#xa;
<mxGeometry x="800" y="542.5" width="120" height="60" as="geometry"/> <mxGeometry x="800" y="542.5" width="120" height="60" as="geometry"/>
&#xa; &#xa;&#xa;
</mxCell> </mxCell>
&#xa; &#xa;&#xa;
<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"> <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">
&#xa; &#xa;&#xa;
<mxGeometry relative="1" as="geometry"/> <mxGeometry relative="1" as="geometry"/>
&#xa; &#xa;&#xa;
</mxCell> </mxCell>
&#xa; &#xa;&#xa;
<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"> <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">
&#xa; &#xa;&#xa;
<mxGeometry relative="1" as="geometry"/> <mxGeometry relative="1" as="geometry"/>
&#xa; &#xa;&#xa;
</mxCell> </mxCell>
&#xa; &#xa;&#xa;
<mxCell id="UY-EM7-1ECCvWtENr50b-2" value="&amp;lt;&amp;lt;Interface&amp;gt;&amp;gt;&lt;br&gt;IServiceManipulator" style="rounded=0;whiteSpace=wrap;html=1;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1"> <mxCell id="UY-EM7-1ECCvWtENr50b-2" value="&amp;lt;&amp;lt;Interface&amp;gt;&amp;gt;&lt;br&gt;IServiceManipulator" style="rounded=0;whiteSpace=wrap;html=1;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
&#xa; &#xa;&#xa;
<mxGeometry x="800" y="432.5" width="120" height="60" as="geometry"/> <mxGeometry x="800" y="432.5" width="120" height="60" as="geometry"/>
&#xa; &#xa;&#xa;
</mxCell> </mxCell>
&#xa; &#xa;&#xa;
<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"> <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">
&#xa; &#xa;&#xa;
<mxGeometry relative="1" as="geometry"/> <mxGeometry relative="1" as="geometry"/>
&#xa; &#xa;&#xa;
</mxCell> </mxCell>
&#xa; &#xa;&#xa;
<mxCell id="UY-EM7-1ECCvWtENr50b-10" value="ServicesResult &amp;lt;DS&amp;gt;" style="rounded=0;whiteSpace=wrap;html=1;fillColor=none;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1"> <mxCell id="UY-EM7-1ECCvWtENr50b-10" value="ServicesResult &amp;lt;DS&amp;gt;" style="rounded=0;whiteSpace=wrap;html=1;fillColor=none;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
&#xa; &#xa;&#xa;
<mxGeometry x="800" y="67.5" width="120" height="60" as="geometry"/> <mxGeometry x="800" y="67.5" width="120" height="60" as="geometry"/>
&#xa; &#xa;&#xa;
</mxCell> </mxCell>
&#xa; &#xa;&#xa;
<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"> <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">
&#xa; &#xa;&#xa;
<mxGeometry relative="1" as="geometry"/> <mxGeometry relative="1" as="geometry"/>
&#xa; &#xa;&#xa;
</mxCell> </mxCell>
&#xa; &#xa;&#xa;
<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"> <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">
&#xa; &#xa;&#xa;
<mxGeometry relative="1" as="geometry"/> <mxGeometry relative="1" as="geometry"/>
&#xa; &#xa;&#xa;
</mxCell> </mxCell>
&#xa; &#xa;&#xa;
<mxCell id="UY-EM7-1ECCvWtENr50b-11" value="&amp;lt;&amp;lt;Interface&amp;gt;&amp;gt;&lt;br&gt;IServicesMonitor" style="rounded=0;whiteSpace=wrap;html=1;fillColor=none;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1"> <mxCell id="UY-EM7-1ECCvWtENr50b-11" value="&amp;lt;&amp;lt;Interface&amp;gt;&amp;gt;&lt;br&gt;IServicesMonitor" style="rounded=0;whiteSpace=wrap;html=1;fillColor=none;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
&#xa; &#xa;&#xa;
<mxGeometry x="800" y="167.5" width="120" height="60" as="geometry"/> <mxGeometry x="800" y="167.5" width="120" height="60" as="geometry"/>
&#xa; &#xa;&#xa;
</mxCell> </mxCell>
&#xa; &#xa;&#xa;
<mxCell id="UY-EM7-1ECCvWtENr50b-70" value="" style="line;strokeWidth=2;direction=south;html=1;fillColor=none;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1"> <mxCell id="UY-EM7-1ECCvWtENr50b-70" value="" style="line;strokeWidth=2;direction=south;html=1;fillColor=none;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
&#xa; &#xa;&#xa;
<mxGeometry x="220" y="50" width="10" height="570" as="geometry"/> <mxGeometry x="220" y="50" width="10" height="570" as="geometry"/>
&#xa; &#xa;&#xa;
</mxCell> </mxCell>
&#xa; &#xa;&#xa;
<mxCell id="UY-EM7-1ECCvWtENr50b-71" value="" style="line;strokeWidth=2;direction=south;html=1;fillColor=none;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1"> <mxCell id="UY-EM7-1ECCvWtENr50b-71" value="" style="line;strokeWidth=2;direction=south;html=1;fillColor=none;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
&#xa; &#xa;&#xa;
<mxGeometry x="760" y="50" width="10" height="570" as="geometry"/> <mxGeometry x="760" y="50" width="10" height="570" as="geometry"/>
&#xa; &#xa;&#xa;
</mxCell> </mxCell>
&#xa; &#xa;&#xa;
<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"> <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">
&#xa; &#xa;&#xa;
<mxGeometry y="870" width="480" height="20" as="geometry"/> <mxGeometry y="870" width="480" height="20" as="geometry"/>
&#xa; &#xa;&#xa;
</mxCell> </mxCell>
&#xa; &#xa;&#xa;
<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"> <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">
&#xa; &#xa;&#xa;
<mxGeometry relative="1" as="geometry"/> <mxGeometry relative="1" as="geometry"/>
&#xa; &#xa;&#xa;
</mxCell> </mxCell>
&#xa; &#xa;&#xa;
<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"> <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">
&#xa; &#xa;&#xa;
<mxGeometry relative="1" as="geometry"/> <mxGeometry relative="1" as="geometry"/>
&#xa; &#xa;&#xa;
</mxCell> </mxCell>
&#xa; &#xa;&#xa;
<mxCell id="tM_Gde3HH8YiZ2frBV5J-0" value="MainPresenter" style="html=1;dashed=0;whitespace=wrap;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1"> <mxCell id="tM_Gde3HH8YiZ2frBV5J-0" value="MainPresenter" style="html=1;dashed=0;whitespace=wrap;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
&#xa; &#xa;&#xa;
<mxGeometry x="420" y="122.5" width="110" height="60" as="geometry"/> <mxGeometry x="420" y="122.5" width="110" height="60" as="geometry"/>
&#xa; &#xa;&#xa;
</mxCell> </mxCell>
&#xa; &#xa;&#xa;
<mxCell id="tM_Gde3HH8YiZ2frBV5J-1" value="&amp;lt;&amp;lt;Interface&amp;gt;&amp;gt;&lt;br&gt;IConsoleOutput" style="html=1;dashed=0;whitespace=wrap;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1"> <mxCell id="tM_Gde3HH8YiZ2frBV5J-1" value="&amp;lt;&amp;lt;Interface&amp;gt;&amp;gt;&lt;br&gt;IConsoleOutput" style="html=1;dashed=0;whitespace=wrap;sketch=1;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
&#xa; &#xa;&#xa;
<mxGeometry x="420" y="20" width="110" height="50" as="geometry"/> <mxGeometry x="420" y="20" width="110" height="50" as="geometry"/>
&#xa; &#xa;&#xa;
</mxCell> </mxCell>
&#xa; &#xa;&#xa;
</root> </root>
&#xa; &#xa;&#xa;
</mxGraphModel> </mxGraphModel>
&#xa; &#xa;&#xa;
</diagram> </diagram>
</mxfile> </mxfile>

View File

@ -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) { }
}
}

View File

@ -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) { }
}
}

View File

@ -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) { }
}
}

View File

@ -1,6 +1,6 @@
namespace GameServiceWarden.ModuleAPI namespace GameServiceWarden.ModuleAPI
{ {
public interface IConfigurable public interface IGameConfigurable
{ {
string OptionName { get; } string OptionName { get; }
bool SetValue(string value); bool SetValue(string value);

View File

@ -7,7 +7,7 @@ namespace GameServiceWarden.ModuleAPI
public interface IGameService public interface IGameService
{ {
event EventHandler<ServiceState> StateChangeEvent; event EventHandler<ServiceState> StateChangeEvent;
IReadOnlyCollection<IConfigurable> Configurables{ get; } IReadOnlyCollection<IGameConfigurable> Configurables{ get; }
void InitializeService(TextWriter stream); void InitializeService(TextWriter stream);
void ElegantShutdown(); void ElegantShutdown();
void ExecuteCommand(string command); void ExecuteCommand(string command);

View File

@ -14,7 +14,7 @@
</ItemGroup> </ItemGroup>
<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" /> <ProjectReference Include="..\..\src\GameServiceWarden.ModuleAPI\GameServiceWarden.ModuleAPI.csproj" />
</ItemGroup> </ItemGroup>

View File

@ -1,13 +1,13 @@
using GameServiceWarden.ModuleAPI; 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; private string value;
public string OptionName { get; private set; } public string OptionName { get; private set; }
public FakeConfigurable(string optionName) public FakeGameConfigurable(string optionName)
{ {
this.OptionName = optionName; this.OptionName = optionName;
} }

View File

@ -3,11 +3,11 @@ using System.Collections.Generic;
using System.IO; using System.IO;
using GameServiceWarden.ModuleAPI; 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; public event EventHandler<ServiceState> StateChangeEvent;
@ -15,10 +15,10 @@ namespace GameServiceWarden.Host.Tests.Modules
private TextWriter consoleStream; private TextWriter consoleStream;
public FakeService(params IConfigurable[] configurables) public FakeGameService(params IGameConfigurable[] configurables)
{ {
HashSet<IConfigurable> modifiable = new HashSet<IConfigurable>(); HashSet<IGameConfigurable> modifiable = new HashSet<IGameConfigurable>();
foreach (IConfigurable configurable in configurables) foreach (IGameConfigurable configurable in configurables)
{ {
modifiable.Add(configurable); modifiable.Add(configurable);
} }

View File

@ -1,7 +1,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using GameServiceWarden.ModuleAPI; using GameServiceWarden.ModuleAPI;
namespace GameServiceWarden.Host.Tests.Modules namespace GameServiceWarden.Core.Tests.Modules.Games
{ {
public class FakeGameServiceModule : IGameServiceModule public class FakeGameServiceModule : IGameServiceModule
{ {
@ -9,8 +9,8 @@ namespace GameServiceWarden.Host.Tests.Modules
public string Description => "A fake module for testing."; public string Description => "A fake module for testing.";
private IConfigurable[] configurables; private IGameConfigurable[] configurables;
public FakeGameServiceModule(params IConfigurable[] configurables) public FakeGameServiceModule(params IGameConfigurable[] configurables)
{ {
this.configurables = configurables; this.configurables = configurables;
} }
@ -19,7 +19,7 @@ namespace GameServiceWarden.Host.Tests.Modules
public IGameService CreateGameService() public IGameService CreateGameService()
{ {
return new FakeService(configurables); return new FakeGameService(configurables);
} }
} }
} }

View File

@ -1,24 +1,24 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using GameServiceWarden.Host.Modules; using GameServiceWarden.Core.Games;
using GameServiceWarden.ModuleAPI; using GameServiceWarden.ModuleAPI;
using Xunit; 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 // Testing convention from: https://docs.microsoft.com/en-us/dotnet/core/testing/unit-testing-best-practices
// Fakes are generic test objects, // Fakes are generic test objects,
// mocks are the objects being asserted upon, // mocks are the objects being asserted upon,
// stubs are objects used as part of the test. // stubs are objects used as part of the test.
public class ServiceInfoTest public class GameServiceInfoTest
{ {
//MethodTested_ScenarioTested_ExpectedBehavior //MethodTested_ScenarioTested_ExpectedBehavior
[Fact] [Fact]
public void Start_FromStopped_StateIsRunning() public void Start_FromStopped_StateIsRunning()
{ {
//Arrange, Act, Assert //Arrange, Act, Assert
IGameService stubGameService = new FakeService(); IGameService stubGameService = new FakeGameService();
ServiceInfo serviceInfo = new ServiceInfo(stubGameService, "FakeModule", "FakeAssembly"); GameServiceInfo serviceInfo = new GameServiceInfo(stubGameService, "FakeModule", "FakeAssembly");
serviceInfo.Start(); serviceInfo.Start();
Assert.Equal(ServiceState.Running, serviceInfo.GetServiceState()); Assert.Equal(ServiceState.Running, serviceInfo.GetServiceState());
serviceInfo.Dispose(); serviceInfo.Dispose();
@ -27,8 +27,8 @@ namespace GameServiceWarden.Host.Tests.Modules
[Fact] [Fact]
public void Stop_FromStart_Stopped() public void Stop_FromStart_Stopped()
{ {
IGameService stubService = new FakeService(); IGameService stubService = new FakeGameService();
ServiceInfo serviceInfo = new ServiceInfo(stubService, "FakeModule", "FakeAssembly"); GameServiceInfo serviceInfo = new GameServiceInfo(stubService, "FakeModule", "FakeAssembly");
serviceInfo.Start(); serviceInfo.Start();
serviceInfo.Stop(); serviceInfo.Stop();
Assert.Equal(ServiceState.Stopped, serviceInfo.GetServiceState()); Assert.Equal(ServiceState.Stopped, serviceInfo.GetServiceState());
@ -39,12 +39,12 @@ namespace GameServiceWarden.Host.Tests.Modules
public void GetConfigurableOptions_ServiceStopped_ReturnsConfigurables() public void GetConfigurableOptions_ServiceStopped_ReturnsConfigurables()
{ {
//Given //Given
FakeService stubService = new FakeService(); FakeGameService stubService = new FakeGameService();
FakeConfigurable stubConfigurable = new FakeConfigurable("Option"); FakeGameConfigurable stubConfigurable = new FakeGameConfigurable("Option");
HashSet<IConfigurable> configurables = new HashSet<IConfigurable>(); HashSet<IGameConfigurable> configurables = new HashSet<IGameConfigurable>();
configurables.Add(stubConfigurable); configurables.Add(stubConfigurable);
stubService.Configurables = configurables; stubService.Configurables = configurables;
ServiceInfo serviceInfo = new ServiceInfo(stubService, "FakeModule", "FakeAssembly"); GameServiceInfo serviceInfo = new GameServiceInfo(stubService, "FakeModule", "FakeAssembly");
//Then //Then
Assert.Contains<string>(stubConfigurable.OptionName, serviceInfo.GetConfigurableOptions()); Assert.Contains<string>(stubConfigurable.OptionName, serviceInfo.GetConfigurableOptions());
serviceInfo.Dispose(); serviceInfo.Dispose();
@ -54,12 +54,12 @@ namespace GameServiceWarden.Host.Tests.Modules
public void SetAndGetConfigurationValue_ServiceStopped_AppropriateValueReturned() public void SetAndGetConfigurationValue_ServiceStopped_AppropriateValueReturned()
{ {
//Given //Given
FakeService stubService = new FakeService(); FakeGameService stubService = new FakeGameService();
FakeConfigurable stubConfigurable = new FakeConfigurable("Option"); FakeGameConfigurable stubConfigurable = new FakeGameConfigurable("Option");
HashSet<IConfigurable> configurables = new HashSet<IConfigurable>(); HashSet<IGameConfigurable> configurables = new HashSet<IGameConfigurable>();
configurables.Add(stubConfigurable); configurables.Add(stubConfigurable);
stubService.Configurables = configurables; stubService.Configurables = configurables;
ServiceInfo serviceInfo = new ServiceInfo(stubService, "FakeModule", "FakeAssembly"); GameServiceInfo serviceInfo = new GameServiceInfo(stubService, "FakeModule", "FakeAssembly");
//When //When
serviceInfo.SetConfigurableValue(stubConfigurable.OptionName, "success"); serviceInfo.SetConfigurableValue(stubConfigurable.OptionName, "success");
//Then //Then
@ -70,8 +70,8 @@ namespace GameServiceWarden.Host.Tests.Modules
public void GetServiceState_ServiceNotStarted_ReturnsStoppedState() public void GetServiceState_ServiceNotStarted_ReturnsStoppedState()
{ {
//Given //Given
IGameService stubService = new FakeService(); IGameService stubService = new FakeGameService();
ServiceInfo serviceInfo = new ServiceInfo(stubService, "FakeModule", "FakeAssembly"); GameServiceInfo serviceInfo = new GameServiceInfo(stubService, "FakeModule", "FakeAssembly");
//Then //Then
Assert.Equal(ServiceState.Stopped, serviceInfo.GetServiceState()); Assert.Equal(ServiceState.Stopped, serviceInfo.GetServiceState());
serviceInfo.Dispose(); serviceInfo.Dispose();
@ -81,8 +81,8 @@ namespace GameServiceWarden.Host.Tests.Modules
public void GetServiceState_ServiceStarted_ReturnsRunningState() public void GetServiceState_ServiceStarted_ReturnsRunningState()
{ {
//Given //Given
IGameService stubService = new FakeService(); IGameService stubService = new FakeGameService();
ServiceInfo serviceInfo = new ServiceInfo(stubService, "FakeModule", "FakeAssembly"); GameServiceInfo serviceInfo = new GameServiceInfo(stubService, "FakeModule", "FakeAssembly");
//When //When
serviceInfo.Start(); serviceInfo.Start();
//Then //Then
@ -95,8 +95,8 @@ namespace GameServiceWarden.Host.Tests.Modules
{ {
//Given //Given
const string MODULE_NAME = "FakeModule"; const string MODULE_NAME = "FakeModule";
IGameService stubService = new FakeService(); IGameService stubService = new FakeGameService();
ServiceInfo serviceInfo = new ServiceInfo(stubService, MODULE_NAME, "FakeAssembly"); GameServiceInfo serviceInfo = new GameServiceInfo(stubService, MODULE_NAME, "FakeAssembly");
//Then //Then
Assert.Equal(MODULE_NAME, serviceInfo.GetModuleName()); Assert.Equal(MODULE_NAME, serviceInfo.GetModuleName());
serviceInfo.Dispose(); serviceInfo.Dispose();
@ -107,8 +107,8 @@ namespace GameServiceWarden.Host.Tests.Modules
{ {
//Given //Given
const string ASSEMBLY_NAME = "FakeAssembly"; const string ASSEMBLY_NAME = "FakeAssembly";
IGameService stubService = new FakeService(); IGameService stubService = new FakeGameService();
ServiceInfo serviceInfo = new ServiceInfo(stubService, "FakeModule", ASSEMBLY_NAME); GameServiceInfo serviceInfo = new GameServiceInfo(stubService, "FakeModule", ASSEMBLY_NAME);
//Then //Then
Assert.Equal(ASSEMBLY_NAME, serviceInfo.GetAssemblyName()); Assert.Equal(ASSEMBLY_NAME, serviceInfo.GetAssemblyName());
serviceInfo.Dispose(); serviceInfo.Dispose();
@ -119,8 +119,8 @@ namespace GameServiceWarden.Host.Tests.Modules
{ {
//Given //Given
const string SERVICE_NAME = "Service"; const string SERVICE_NAME = "Service";
IGameService stubService = new FakeService(); IGameService stubService = new FakeGameService();
ServiceInfo serviceInfo = new ServiceInfo(stubService, "FakeModule", "FakeAssemblyName"); GameServiceInfo serviceInfo = new GameServiceInfo(stubService, "FakeModule", "FakeAssemblyName");
//When //When
serviceInfo.ServiceName = SERVICE_NAME; serviceInfo.ServiceName = SERVICE_NAME;
//Then //Then
@ -132,8 +132,8 @@ namespace GameServiceWarden.Host.Tests.Modules
public void ServiceConsoleStream_ServiceNotStarted_NullReturned() public void ServiceConsoleStream_ServiceNotStarted_NullReturned()
{ {
//Given //Given
IGameService stubService = new FakeService(); IGameService stubService = new FakeGameService();
ServiceInfo serviceInfo = new ServiceInfo(stubService, "FakeModule", "FakeAssembly"); GameServiceInfo serviceInfo = new GameServiceInfo(stubService, "FakeModule", "FakeAssembly");
//Then //Then
Assert.Null(serviceInfo.ServiceConsoleStream); Assert.Null(serviceInfo.ServiceConsoleStream);
serviceInfo.Dispose(); serviceInfo.Dispose();
@ -143,8 +143,8 @@ namespace GameServiceWarden.Host.Tests.Modules
public void ServiceConsoleStream_ServiceStarted_StreamReturned() public void ServiceConsoleStream_ServiceStarted_StreamReturned()
{ {
//Given //Given
IGameService stubService = new FakeService(); IGameService stubService = new FakeGameService();
ServiceInfo serviceInfo = new ServiceInfo(stubService, "FakeModule", "FakeAssembly"); GameServiceInfo serviceInfo = new GameServiceInfo(stubService, "FakeModule", "FakeAssembly");
//When //When
serviceInfo.Start(); serviceInfo.Start();
//Then //Then

View File

@ -1,18 +1,18 @@
using System.IO; using System.IO;
using GameServiceWarden.Host.Modules; using GameServiceWarden.Core.Games;
using GameServiceWarden.ModuleAPI; using GameServiceWarden.ModuleAPI;
using Xunit; using Xunit;
namespace GameServiceWarden.Host.Tests.Modules namespace GameServiceWarden.Core.Tests.Modules.Games
{ {
public class ServiceManagerTest public class GameServiceManagerTest
{ {
[Fact] [Fact]
public void AddModule_NewManager_SuccessfulAddition() public void AddModule_NewManager_SuccessfulAddition()
{ {
//Given //Given
const string ASSEMBLY_NAME = "FakeAssembly"; const string ASSEMBLY_NAME = "FakeAssembly";
ServiceManager serviceManager = new ServiceManager(); GameServiceManager serviceManager = new GameServiceManager();
IGameServiceModule stubGameServiceModule = new FakeGameServiceModule(); IGameServiceModule stubGameServiceModule = new FakeGameServiceModule();
//When //When
serviceManager.AddModule(ASSEMBLY_NAME, stubGameServiceModule); serviceManager.AddModule(ASSEMBLY_NAME, stubGameServiceModule);
@ -26,7 +26,7 @@ namespace GameServiceWarden.Host.Tests.Modules
{ {
//Given //Given
const string ASSEMBLY_NAME = "FakeAssembly"; const string ASSEMBLY_NAME = "FakeAssembly";
ServiceManager serviceManager = new ServiceManager(); GameServiceManager serviceManager = new GameServiceManager();
IGameServiceModule stubGameServiceModule = new FakeGameServiceModule(); IGameServiceModule stubGameServiceModule = new FakeGameServiceModule();
//When //When
serviceManager.AddModule(ASSEMBLY_NAME, stubGameServiceModule); serviceManager.AddModule(ASSEMBLY_NAME, stubGameServiceModule);
@ -41,7 +41,7 @@ namespace GameServiceWarden.Host.Tests.Modules
//Given //Given
const string ASSEMBLY_NAME = "FakeAssembly"; const string ASSEMBLY_NAME = "FakeAssembly";
const string FAKE_SERVICE_NAME = "FakeService"; const string FAKE_SERVICE_NAME = "FakeService";
ServiceManager serviceManager = new ServiceManager(); GameServiceManager serviceManager = new GameServiceManager();
IGameServiceModule stubGameServiceModule = new FakeGameServiceModule(); IGameServiceModule stubGameServiceModule = new FakeGameServiceModule();
serviceManager.AddModule(ASSEMBLY_NAME, stubGameServiceModule); serviceManager.AddModule(ASSEMBLY_NAME, stubGameServiceModule);
//When //When
@ -56,7 +56,7 @@ namespace GameServiceWarden.Host.Tests.Modules
//Given //Given
const string ASSEMBLY_NAME = "FakeAssembly"; const string ASSEMBLY_NAME = "FakeAssembly";
const string FAKE_SERVICE_NAME = "FakeService"; const string FAKE_SERVICE_NAME = "FakeService";
ServiceManager serviceManager = new ServiceManager(); GameServiceManager serviceManager = new GameServiceManager();
IGameServiceModule stubGameServiceModule = new FakeGameServiceModule(); IGameServiceModule stubGameServiceModule = new FakeGameServiceModule();
serviceManager.AddModule(ASSEMBLY_NAME, stubGameServiceModule); serviceManager.AddModule(ASSEMBLY_NAME, stubGameServiceModule);
serviceManager.CreateService(FAKE_SERVICE_NAME, ASSEMBLY_NAME, stubGameServiceModule.Name); serviceManager.CreateService(FAKE_SERVICE_NAME, ASSEMBLY_NAME, stubGameServiceModule.Name);
@ -72,7 +72,7 @@ namespace GameServiceWarden.Host.Tests.Modules
//Given //Given
const string ASSEMBLY_NAME = "FakeAssembly"; const string ASSEMBLY_NAME = "FakeAssembly";
const string FAKE_SERVICE_PREFIX = "FakeService_"; const string FAKE_SERVICE_PREFIX = "FakeService_";
ServiceManager serviceManager = new ServiceManager(); GameServiceManager serviceManager = new GameServiceManager();
IGameServiceModule stubGameServiceModule = new FakeGameServiceModule(); IGameServiceModule stubGameServiceModule = new FakeGameServiceModule();
//When //When
serviceManager.AddModule(ASSEMBLY_NAME, stubGameServiceModule); serviceManager.AddModule(ASSEMBLY_NAME, stubGameServiceModule);
@ -93,11 +93,11 @@ namespace GameServiceWarden.Host.Tests.Modules
//Given //Given
const string ASSEMBLY_NAME = "FakeAssembly"; const string ASSEMBLY_NAME = "FakeAssembly";
const string SERVICE_NAME = "FakeService"; const string SERVICE_NAME = "FakeService";
ServiceManager serviceManager = new ServiceManager(); GameServiceManager serviceManager = new GameServiceManager();
IGameServiceModule stubGameServiceModule = new FakeGameServiceModule( IGameServiceModule stubGameServiceModule = new FakeGameServiceModule(
new FakeConfigurable("A"), new FakeGameConfigurable("A"),
new FakeConfigurable("B"), new FakeGameConfigurable("B"),
new FakeConfigurable("C") new FakeGameConfigurable("C")
); );
//When //When
serviceManager.AddModule(ASSEMBLY_NAME, stubGameServiceModule); serviceManager.AddModule(ASSEMBLY_NAME, stubGameServiceModule);
@ -114,9 +114,9 @@ namespace GameServiceWarden.Host.Tests.Modules
//Given //Given
const string ASSEMBLY_NAME = "FakeAssembly"; const string ASSEMBLY_NAME = "FakeAssembly";
const string SERVICE_NAME = "FakeService"; const string SERVICE_NAME = "FakeService";
ServiceManager serviceManager = new ServiceManager(); GameServiceManager serviceManager = new GameServiceManager();
IGameServiceModule stubGameServiceModule = new FakeGameServiceModule( IGameServiceModule stubGameServiceModule = new FakeGameServiceModule(
new FakeConfigurable("A") new FakeGameConfigurable("A")
); );
//When //When
serviceManager.AddModule(ASSEMBLY_NAME, stubGameServiceModule); serviceManager.AddModule(ASSEMBLY_NAME, stubGameServiceModule);
@ -132,7 +132,7 @@ namespace GameServiceWarden.Host.Tests.Modules
//Given //Given
const string ASSEMBLY_NAME = "FakeAssembly"; const string ASSEMBLY_NAME = "FakeAssembly";
const string SERVICE_NAME = "FakeService"; const string SERVICE_NAME = "FakeService";
ServiceManager serviceManager = new ServiceManager(); GameServiceManager serviceManager = new GameServiceManager();
IGameServiceModule stubGameServiceModule = new FakeGameServiceModule(); IGameServiceModule stubGameServiceModule = new FakeGameServiceModule();
//When //When
serviceManager.AddModule(ASSEMBLY_NAME, stubGameServiceModule); serviceManager.AddModule(ASSEMBLY_NAME, stubGameServiceModule);
@ -147,7 +147,7 @@ namespace GameServiceWarden.Host.Tests.Modules
//Given //Given
const string ASSEMBLY_NAME = "FakeAssembly"; const string ASSEMBLY_NAME = "FakeAssembly";
const string SERVICE_NAME = "FakeService"; const string SERVICE_NAME = "FakeService";
ServiceManager serviceManager = new ServiceManager(); GameServiceManager serviceManager = new GameServiceManager();
IGameServiceModule stubGameServiceModule = new FakeGameServiceModule(); IGameServiceModule stubGameServiceModule = new FakeGameServiceModule();
//When //When
serviceManager.AddModule(ASSEMBLY_NAME, stubGameServiceModule); serviceManager.AddModule(ASSEMBLY_NAME, stubGameServiceModule);
@ -163,7 +163,7 @@ namespace GameServiceWarden.Host.Tests.Modules
//Given //Given
const string ASSEMBLY_NAME = "FakeAssembly"; const string ASSEMBLY_NAME = "FakeAssembly";
const string SERVICE_NAME = "FakeService"; const string SERVICE_NAME = "FakeService";
ServiceManager serviceManager = new ServiceManager(); GameServiceManager serviceManager = new GameServiceManager();
IGameServiceModule stubGameServiceModule = new FakeGameServiceModule(); IGameServiceModule stubGameServiceModule = new FakeGameServiceModule();
//When //When
serviceManager.AddModule(ASSEMBLY_NAME, stubGameServiceModule); serviceManager.AddModule(ASSEMBLY_NAME, stubGameServiceModule);
@ -179,7 +179,7 @@ namespace GameServiceWarden.Host.Tests.Modules
//Given //Given
const string ASSEMBLY_NAME = "FakeAssembly"; const string ASSEMBLY_NAME = "FakeAssembly";
const string SERVICE_NAME = "FakeService"; const string SERVICE_NAME = "FakeService";
ServiceManager serviceManager = new ServiceManager(); GameServiceManager serviceManager = new GameServiceManager();
IGameServiceModule stubGameServiceModule = new FakeGameServiceModule(); IGameServiceModule stubGameServiceModule = new FakeGameServiceModule();
//When //When
serviceManager.AddModule(ASSEMBLY_NAME, stubGameServiceModule); serviceManager.AddModule(ASSEMBLY_NAME, stubGameServiceModule);
@ -196,7 +196,7 @@ namespace GameServiceWarden.Host.Tests.Modules
//Given //Given
const string ASSEMBLY_NAME = "FakeAssembly"; const string ASSEMBLY_NAME = "FakeAssembly";
const string SERVICE_NAME = "FakeService"; const string SERVICE_NAME = "FakeService";
ServiceManager serviceManager = new ServiceManager(); GameServiceManager serviceManager = new GameServiceManager();
IGameServiceModule stubGameServiceModule = new FakeGameServiceModule(); IGameServiceModule stubGameServiceModule = new FakeGameServiceModule();
//When //When
serviceManager.AddModule(ASSEMBLY_NAME, stubGameServiceModule); serviceManager.AddModule(ASSEMBLY_NAME, stubGameServiceModule);
@ -218,7 +218,7 @@ namespace GameServiceWarden.Host.Tests.Modules
//Given //Given
const string ASSEMBLY_NAME = "FakeAssembly"; const string ASSEMBLY_NAME = "FakeAssembly";
const string SERVICE_NAME = "FakeService"; const string SERVICE_NAME = "FakeService";
ServiceManager serviceManager = new ServiceManager(); GameServiceManager serviceManager = new GameServiceManager();
IGameServiceModule stubGameServiceModule = new FakeGameServiceModule(); IGameServiceModule stubGameServiceModule = new FakeGameServiceModule();
//When //When
serviceManager.AddModule(ASSEMBLY_NAME, stubGameServiceModule); serviceManager.AddModule(ASSEMBLY_NAME, stubGameServiceModule);