removed async methods, for some reason just results in null.. no exceptions anywhere :(

added protection to prevent reloading assemblies already in the domain.
corrected bug only identifying INotifierProviderFactory types.
This commit is contained in:
chris.watts90@outlook.com 2017-06-23 22:56:23 +01:00
commit 17d50b5be1
17 changed files with 192 additions and 57 deletions

View File

@ -2,6 +2,6 @@
{ {
public interface INotifierProviderFactory public interface INotifierProviderFactory
{ {
INotifierProvider CreateProvider(); INotifierProvider GetProvider();
} }
} }

View File

@ -0,0 +1,7 @@
namespace Interfaces
{
public interface ISystemControl
{
void Shutdown();
}
}

View File

@ -0,0 +1,10 @@
using System.Collections.Generic;
namespace Interfaces
{
public interface ISystemControlManager
{
List<string> GetAvailableProviders();
void Shutdown();
}
}

View File

@ -0,0 +1,7 @@
namespace Interfaces
{
public interface ISystemControlProviderFactory
{
ISystemControl GetProvider();
}
}

View File

@ -0,0 +1,7 @@
namespace Interfaces
{
public interface ITransponderUtilities
{
int GetLastScannedIdAsync();
}
}

View File

@ -0,0 +1,7 @@
namespace Interfaces
{
public interface ITransponderUtilityProviderFactory
{
ITransponderUtilities GetProvider();
}
}

View File

@ -50,6 +50,11 @@
<Compile Include="INotifierManager.cs" /> <Compile Include="INotifierManager.cs" />
<Compile Include="INotifierProvider.cs" /> <Compile Include="INotifierProvider.cs" />
<Compile Include="INotifierProviderFactory.cs" /> <Compile Include="INotifierProviderFactory.cs" />
<Compile Include="ISystemControl.cs" />
<Compile Include="ISystemControlManager.cs" />
<Compile Include="ISystemControlProviderFactory.cs" />
<Compile Include="ITransponderUtilities.cs" />
<Compile Include="ITransponderUtilityProviderFactory.cs" />
<Compile Include="NotificationEventArgs.cs" /> <Compile Include="NotificationEventArgs.cs" />
<Compile Include="Pilot.cs" /> <Compile Include="Pilot.cs" />
<Compile Include="ProviderDetails.cs" /> <Compile Include="ProviderDetails.cs" />

View File

@ -0,0 +1,21 @@
using System.Diagnostics;
using Interfaces;
namespace IrDaemonNotifier
{
public class IrDaemonController:ISystemControl
{
public void Shutdown()
{
Debug.WriteLine("test");
}
}
public class IrDaemonControllerProviderFactory : ISystemControlProviderFactory
{
public ISystemControl GetProvider()
{
return new IrDaemonController();
}
}
}

View File

@ -40,6 +40,7 @@
<Reference Include="System.Xml" /> <Reference Include="System.Xml" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="IrDaemonController.cs" />
<Compile Include="IrDaemonNotifier.cs" /> <Compile Include="IrDaemonNotifier.cs" />
<Compile Include="IrDaemonNotifierProviderFactory.cs" /> <Compile Include="IrDaemonNotifierProviderFactory.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />

View File

@ -15,7 +15,7 @@ namespace IrDaemonNotifier
{ {
_logger = logger; _logger = logger;
} }
public INotifierProvider CreateProvider() public INotifierProvider GetProvider()
{ {
return new IrDaemonNotifier(_logger); return new IrDaemonNotifier(_logger);
} }

View File

@ -1,5 +1,4 @@
using System.Diagnostics; using System.IO;
using System.IO;
using Interfaces; using Interfaces;
using Nancy; using Nancy;
using Nancy.Authentication.Forms; using Nancy.Authentication.Forms;
@ -7,11 +6,10 @@ using Nancy.Bootstrapper;
using Nancy.Bootstrappers.Ninject; using Nancy.Bootstrappers.Ninject;
using Nancy.Conventions; using Nancy.Conventions;
using Nancy.Diagnostics; using Nancy.Diagnostics;
using Nancy.TinyIoc;
using Ninject; using Ninject;
using RaceLapTimer.ApiControllers;
using RaceLapTimer.Extensions; using RaceLapTimer.Extensions;
using RaceLapTimer.Extensions.Notifications; using RaceLapTimer.Extensions.Notifications;
using RaceLapTimer.Extensions.SystemControl;
namespace RaceLapTimer namespace RaceLapTimer
{ {
@ -39,10 +37,10 @@ namespace RaceLapTimer
container.Load(cfgFilePath); container.Load(cfgFilePath);
container.Bind<INotifierManager>().To<NotificationManager>().InSingletonScope(); container.Bind<INotifierManager>().To<NotificationManager>().InSingletonScope();
container.Bind<ISystemControlManager>().To<SystemControlManager>().InSingletonScope();
var sM = container.Get<ISystemControlManager>();
//var nM = container.Get<INotifierManager>(); sM.Shutdown();
//nM.NotifyRaceStarted(new NotificationEventArgs());
} }
protected override void ConfigureRequestContainer(IKernel container, NancyContext context) protected override void ConfigureRequestContainer(IKernel container, NancyContext context)

View File

@ -3,11 +3,11 @@ using System.Collections.Generic;
using Interfaces; using Interfaces;
using Ninject; using Ninject;
namespace RaceLapTimer.Extensions.Notifications namespace RaceLapTimer.Extensions
{ {
class ContainerHelper : IContainerHelper class ContainerHelper : IContainerHelper
{ {
private IKernel _container; private readonly IKernel _container;
public ContainerHelper(IKernel container) public ContainerHelper(IKernel container)
{ {
_container = container; _container = container;

View File

@ -1,9 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.IO;
using System.Linq; using System.Linq;
using System.Reflection;
using System.Threading.Tasks; using System.Threading.Tasks;
using Interfaces; using Interfaces;
@ -18,13 +16,13 @@ namespace RaceLapTimer.Extensions.Notifications
RegisterProviders(locator); RegisterProviders(locator);
} }
private async void RegisterProviders(IPluginLocator locator) private void RegisterProviders(IPluginLocator locator)
{ {
var providerFactories = await locator.LocateAsync<INotifierProviderFactory>(); var providerFactories = locator.Locate<INotifierProviderFactory>();
_providers = new List<INotifierProvider>(); _providers = new List<INotifierProvider>();
foreach (var factory in providerFactories) foreach (var factory in providerFactories)
{ {
_providers.Add(factory.CreateProvider()); _providers.Add(factory.GetProvider());
} }
} }

View File

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
@ -13,11 +14,13 @@ namespace RaceLapTimer.Extensions
{ {
private readonly IContainerHelper _helper; private readonly IContainerHelper _helper;
private readonly IPluginPathProvider _pluginPath; private readonly IPluginPathProvider _pluginPath;
private readonly ILoggerService _logger;
public PluginLocator(IContainerHelper helper, IPluginPathProvider pluginPath) public PluginLocator(IContainerHelper helper, IPluginPathProvider pluginPath, ILoggerService logger)
{ {
_helper = helper; _helper = helper;
_pluginPath = pluginPath; _pluginPath = pluginPath;
_logger = logger;
} }
public async Task<List<T>> LocateAsync<T>() public async Task<List<T>> LocateAsync<T>()
@ -26,6 +29,8 @@ namespace RaceLapTimer.Extensions
} }
public List<T> Locate<T>() public List<T> Locate<T>()
{
try
{ {
if (!Directory.Exists(_pluginPath.GetPluginPath)) return new List<T>(); if (!Directory.Exists(_pluginPath.GetPluginPath)) return new List<T>();
var files = Directory.GetFiles(_pluginPath.GetPluginPath); var files = Directory.GetFiles(_pluginPath.GetPluginPath);
@ -38,7 +43,7 @@ namespace RaceLapTimer.Extensions
var assembly = Assembly.ReflectionOnlyLoadFrom(file); var assembly = Assembly.ReflectionOnlyLoadFrom(file);
var pluginTypes = (from t in assembly.GetExportedTypes() var pluginTypes = (from t in assembly.GetExportedTypes()
where t.GetInterfaces().Any(x => x.Name == nameof(INotifierProviderFactory)) where t.GetInterfaces().Any(x => x.Name == typeof(T).Name)
select t).ToList(); select t).ToList();
if (pluginTypes.Any()) if (pluginTypes.Any())
{ {
@ -46,7 +51,7 @@ namespace RaceLapTimer.Extensions
{ {
FilePath = file, FilePath = file,
PluginType = pluginTypes.First(), PluginType = pluginTypes.First(),
TypeToBindTo = typeof(INotifierProviderFactory), TypeToBindTo = typeof(T),
UniqueName = Path.GetFileNameWithoutExtension(file) UniqueName = Path.GetFileNameWithoutExtension(file)
}); });
} }
@ -54,8 +59,10 @@ namespace RaceLapTimer.Extensions
foreach (var plugin in discoveryList) foreach (var plugin in discoveryList)
{ {
//load into the appDomain.. var assy = AssemblyIsLoaded(plugin.FilePath)
var assy = Assembly.LoadFrom(plugin.FilePath); ? GetAssemblyFromAppDomain(plugin.FilePath)
: Assembly.LoadFrom(plugin.FilePath);
//register our type //register our type
var pluginTypes = var pluginTypes =
(from t in assy.GetExportedTypes() (from t in assy.GetExportedTypes()
@ -70,6 +77,25 @@ namespace RaceLapTimer.Extensions
return _helper.GetAll<T>().ToList(); return _helper.GetAll<T>().ToList();
} }
catch (Exception ex)
{
_logger.Error(ex);
return new List<T>();
}
}
private Assembly GetAssemblyFromAppDomain(string pluginFilePath)
{
var name = Path.GetFileName(pluginFilePath);
return AppDomain.CurrentDomain.GetAssemblies().First(x => x.ManifestModule.Name == name);
}
private bool AssemblyIsLoaded(string pluginFilePath)
{
var name = Path.GetFileName(pluginFilePath);
var d = AppDomain.CurrentDomain.GetAssemblies().Where(x => x.ManifestModule.Name == name);
return d.Any();
}
private bool IsAssembly(string extension) private bool IsAssembly(string extension)
{ {
@ -78,11 +104,7 @@ namespace RaceLapTimer.Extensions
"dll", "exe" "dll", "exe"
}; };
var ext = extension.Remove(0, 1); var ext = extension.Remove(0, 1);
if (validAssemblyExts.Contains(ext)) return validAssemblyExts.Contains(ext);
{
return true;
}
return false;
} }
private class DiscoveredPlugin private class DiscoveredPlugin

View File

@ -0,0 +1,51 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Interfaces;
namespace RaceLapTimer.Extensions.SystemControl
{
class SystemControlManager : ISystemControlManager
{
private List<ISystemControl> _providers;
private readonly ILoggerService _logger;
public SystemControlManager(IPluginLocator locator, ILoggerService logger)
{
RegisterProviders(locator);
_logger = logger;
}
private void RegisterProviders(IPluginLocator locator)
{
try
{
var providerFactories = locator.Locate<ISystemControlProviderFactory>();
_providers = new List<ISystemControl>();
foreach (var factory in providerFactories)
{
_providers.Add(factory.GetProvider());
}
}
catch (Exception ex)
{
_logger.Error(ex);
}
}
public List<string> GetAvailableProviders()
{
return _providers.Select(x=>x.GetType().ToString()).ToList();
}
public void Shutdown()
{
foreach (var provider in _providers)
{
Task.Factory.StartNew(() => provider.Shutdown());
}
}
}
}

View File

@ -115,6 +115,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="Extensions\PluginLocator.cs" /> <Compile Include="Extensions\PluginLocator.cs" />
<Compile Include="Extensions\SystemControl\SystemControlManager.cs" />
<Compile Include="IDbProvider.cs" /> <Compile Include="IDbProvider.cs" />
<Compile Include="ApiControllers\LapTrackApiModule.cs" /> <Compile Include="ApiControllers\LapTrackApiModule.cs" />
<Compile Include="ApiControllers\MonitorApiModule.cs" /> <Compile Include="ApiControllers\MonitorApiModule.cs" />
@ -126,7 +127,7 @@
<Compile Include="TestProvider.cs" /> <Compile Include="TestProvider.cs" />
<Compile Include="AuthenticationBootstrapper.cs" /> <Compile Include="AuthenticationBootstrapper.cs" />
<Compile Include="ConfigFilePathProvider.cs" /> <Compile Include="ConfigFilePathProvider.cs" />
<Compile Include="Extensions\Notifications\ContainerHelper.cs" /> <Compile Include="Extensions\ContainerHelper.cs" />
<Compile Include="Extensions\Notifications\NotificationManager.cs" /> <Compile Include="Extensions\Notifications\NotificationManager.cs" />
<Compile Include="Modules\HistoryModule.cs" /> <Compile Include="Modules\HistoryModule.cs" />
<Compile Include="ApiControllers\InfoApiModule.cs" /> <Compile Include="ApiControllers\InfoApiModule.cs" />

View File

@ -15,7 +15,7 @@ namespace UdpNotifier
_logger = logger; _logger = logger;
} }
public INotifierProvider CreateProvider() public INotifierProvider GetProvider()
{ {
return new UdpNotifierProvider(_logger); return new UdpNotifierProvider(_logger);
} }