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:
commit
17d50b5be1
@ -2,6 +2,6 @@
|
||||
{
|
||||
public interface INotifierProviderFactory
|
||||
{
|
||||
INotifierProvider CreateProvider();
|
||||
INotifierProvider GetProvider();
|
||||
}
|
||||
}
|
||||
|
||||
7
RaceLapTimer/Interfaces/ISystemControl.cs
Normal file
7
RaceLapTimer/Interfaces/ISystemControl.cs
Normal file
@ -0,0 +1,7 @@
|
||||
namespace Interfaces
|
||||
{
|
||||
public interface ISystemControl
|
||||
{
|
||||
void Shutdown();
|
||||
}
|
||||
}
|
||||
10
RaceLapTimer/Interfaces/ISystemControlManager.cs
Normal file
10
RaceLapTimer/Interfaces/ISystemControlManager.cs
Normal file
@ -0,0 +1,10 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Interfaces
|
||||
{
|
||||
public interface ISystemControlManager
|
||||
{
|
||||
List<string> GetAvailableProviders();
|
||||
void Shutdown();
|
||||
}
|
||||
}
|
||||
7
RaceLapTimer/Interfaces/ISystemControlProviderFactory.cs
Normal file
7
RaceLapTimer/Interfaces/ISystemControlProviderFactory.cs
Normal file
@ -0,0 +1,7 @@
|
||||
namespace Interfaces
|
||||
{
|
||||
public interface ISystemControlProviderFactory
|
||||
{
|
||||
ISystemControl GetProvider();
|
||||
}
|
||||
}
|
||||
7
RaceLapTimer/Interfaces/ITransponderUtilities.cs
Normal file
7
RaceLapTimer/Interfaces/ITransponderUtilities.cs
Normal file
@ -0,0 +1,7 @@
|
||||
namespace Interfaces
|
||||
{
|
||||
public interface ITransponderUtilities
|
||||
{
|
||||
int GetLastScannedIdAsync();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,7 @@
|
||||
namespace Interfaces
|
||||
{
|
||||
public interface ITransponderUtilityProviderFactory
|
||||
{
|
||||
ITransponderUtilities GetProvider();
|
||||
}
|
||||
}
|
||||
@ -50,6 +50,11 @@
|
||||
<Compile Include="INotifierManager.cs" />
|
||||
<Compile Include="INotifierProvider.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="Pilot.cs" />
|
||||
<Compile Include="ProviderDetails.cs" />
|
||||
|
||||
21
RaceLapTimer/IrDaemonNotifier/IrDaemonController.cs
Normal file
21
RaceLapTimer/IrDaemonNotifier/IrDaemonController.cs
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -40,6 +40,7 @@
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="IrDaemonController.cs" />
|
||||
<Compile Include="IrDaemonNotifier.cs" />
|
||||
<Compile Include="IrDaemonNotifierProviderFactory.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
|
||||
@ -15,7 +15,7 @@ namespace IrDaemonNotifier
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
public INotifierProvider CreateProvider()
|
||||
public INotifierProvider GetProvider()
|
||||
{
|
||||
return new IrDaemonNotifier(_logger);
|
||||
}
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.IO;
|
||||
using Interfaces;
|
||||
using Nancy;
|
||||
using Nancy.Authentication.Forms;
|
||||
@ -7,11 +6,10 @@ using Nancy.Bootstrapper;
|
||||
using Nancy.Bootstrappers.Ninject;
|
||||
using Nancy.Conventions;
|
||||
using Nancy.Diagnostics;
|
||||
using Nancy.TinyIoc;
|
||||
using Ninject;
|
||||
using RaceLapTimer.ApiControllers;
|
||||
using RaceLapTimer.Extensions;
|
||||
using RaceLapTimer.Extensions.Notifications;
|
||||
using RaceLapTimer.Extensions.SystemControl;
|
||||
|
||||
namespace RaceLapTimer
|
||||
{
|
||||
@ -39,10 +37,10 @@ namespace RaceLapTimer
|
||||
container.Load(cfgFilePath);
|
||||
|
||||
container.Bind<INotifierManager>().To<NotificationManager>().InSingletonScope();
|
||||
|
||||
container.Bind<ISystemControlManager>().To<SystemControlManager>().InSingletonScope();
|
||||
|
||||
//var nM = container.Get<INotifierManager>();
|
||||
//nM.NotifyRaceStarted(new NotificationEventArgs());
|
||||
var sM = container.Get<ISystemControlManager>();
|
||||
sM.Shutdown();
|
||||
}
|
||||
|
||||
protected override void ConfigureRequestContainer(IKernel container, NancyContext context)
|
||||
|
||||
@ -3,11 +3,11 @@ using System.Collections.Generic;
|
||||
using Interfaces;
|
||||
using Ninject;
|
||||
|
||||
namespace RaceLapTimer.Extensions.Notifications
|
||||
namespace RaceLapTimer.Extensions
|
||||
{
|
||||
class ContainerHelper : IContainerHelper
|
||||
{
|
||||
private IKernel _container;
|
||||
private readonly IKernel _container;
|
||||
public ContainerHelper(IKernel container)
|
||||
{
|
||||
_container = container;
|
||||
@ -1,9 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using Interfaces;
|
||||
|
||||
@ -18,13 +16,13 @@ namespace RaceLapTimer.Extensions.Notifications
|
||||
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>();
|
||||
foreach (var factory in providerFactories)
|
||||
{
|
||||
_providers.Add(factory.CreateProvider());
|
||||
_providers.Add(factory.GetProvider());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
@ -13,11 +14,13 @@ namespace RaceLapTimer.Extensions
|
||||
{
|
||||
private readonly IContainerHelper _helper;
|
||||
private readonly IPluginPathProvider _pluginPath;
|
||||
private readonly ILoggerService _logger;
|
||||
|
||||
public PluginLocator(IContainerHelper helper, IPluginPathProvider pluginPath)
|
||||
public PluginLocator(IContainerHelper helper, IPluginPathProvider pluginPath, ILoggerService logger)
|
||||
{
|
||||
_helper = helper;
|
||||
_pluginPath = pluginPath;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public async Task<List<T>> LocateAsync<T>()
|
||||
@ -27,48 +30,71 @@ namespace RaceLapTimer.Extensions
|
||||
|
||||
public List<T> Locate<T>()
|
||||
{
|
||||
if (!Directory.Exists(_pluginPath.GetPluginPath)) return new List<T>();
|
||||
var files = Directory.GetFiles(_pluginPath.GetPluginPath);
|
||||
var discoveryList = new List<DiscoveredPlugin>();
|
||||
|
||||
foreach (var file in files)
|
||||
try
|
||||
{
|
||||
var ext = Path.GetExtension(file);
|
||||
if (!IsAssembly(ext)) continue;
|
||||
if (!Directory.Exists(_pluginPath.GetPluginPath)) return new List<T>();
|
||||
var files = Directory.GetFiles(_pluginPath.GetPluginPath);
|
||||
var discoveryList = new List<DiscoveredPlugin>();
|
||||
|
||||
var assembly = Assembly.ReflectionOnlyLoadFrom(file);
|
||||
var pluginTypes = (from t in assembly.GetExportedTypes()
|
||||
where t.GetInterfaces().Any(x => x.Name == nameof(INotifierProviderFactory))
|
||||
select t).ToList();
|
||||
if (pluginTypes.Any())
|
||||
foreach (var file in files)
|
||||
{
|
||||
discoveryList.Add(new DiscoveredPlugin
|
||||
var ext = Path.GetExtension(file);
|
||||
if (!IsAssembly(ext)) continue;
|
||||
|
||||
var assembly = Assembly.ReflectionOnlyLoadFrom(file);
|
||||
var pluginTypes = (from t in assembly.GetExportedTypes()
|
||||
where t.GetInterfaces().Any(x => x.Name == typeof(T).Name)
|
||||
select t).ToList();
|
||||
if (pluginTypes.Any())
|
||||
{
|
||||
FilePath = file,
|
||||
PluginType = pluginTypes.First(),
|
||||
TypeToBindTo = typeof(INotifierProviderFactory),
|
||||
UniqueName = Path.GetFileNameWithoutExtension(file)
|
||||
});
|
||||
discoveryList.Add(new DiscoveredPlugin
|
||||
{
|
||||
FilePath = file,
|
||||
PluginType = pluginTypes.First(),
|
||||
TypeToBindTo = typeof(T),
|
||||
UniqueName = Path.GetFileNameWithoutExtension(file)
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var plugin in discoveryList)
|
||||
foreach (var plugin in discoveryList)
|
||||
{
|
||||
var assy = AssemblyIsLoaded(plugin.FilePath)
|
||||
? GetAssemblyFromAppDomain(plugin.FilePath)
|
||||
: Assembly.LoadFrom(plugin.FilePath);
|
||||
|
||||
//register our type
|
||||
var pluginTypes =
|
||||
(from t in assy.GetExportedTypes()
|
||||
where t.GetInterfaces().Any(x => x.Name == plugin.TypeToBindTo.Name)
|
||||
select t).ToList();
|
||||
|
||||
if (!pluginTypes.Any()) continue;
|
||||
|
||||
var pg = pluginTypes.First();
|
||||
_helper.RegisterType(plugin.TypeToBindTo, pg, plugin.UniqueName);
|
||||
}
|
||||
|
||||
return _helper.GetAll<T>().ToList();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
//load into the appDomain..
|
||||
var assy = Assembly.LoadFrom(plugin.FilePath);
|
||||
//register our type
|
||||
var pluginTypes =
|
||||
(from t in assy.GetExportedTypes()
|
||||
where t.GetInterfaces().Any(x => x.Name == plugin.TypeToBindTo.Name)
|
||||
select t).ToList();
|
||||
|
||||
if (!pluginTypes.Any()) continue;
|
||||
|
||||
var pg = pluginTypes.First();
|
||||
_helper.RegisterType(plugin.TypeToBindTo, pg, plugin.UniqueName);
|
||||
_logger.Error(ex);
|
||||
return new List<T>();
|
||||
}
|
||||
}
|
||||
|
||||
return _helper.GetAll<T>().ToList();
|
||||
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)
|
||||
@ -78,11 +104,7 @@ namespace RaceLapTimer.Extensions
|
||||
"dll", "exe"
|
||||
};
|
||||
var ext = extension.Remove(0, 1);
|
||||
if (validAssemblyExts.Contains(ext))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return validAssemblyExts.Contains(ext);
|
||||
}
|
||||
|
||||
private class DiscoveredPlugin
|
||||
|
||||
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -115,6 +115,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Extensions\PluginLocator.cs" />
|
||||
<Compile Include="Extensions\SystemControl\SystemControlManager.cs" />
|
||||
<Compile Include="IDbProvider.cs" />
|
||||
<Compile Include="ApiControllers\LapTrackApiModule.cs" />
|
||||
<Compile Include="ApiControllers\MonitorApiModule.cs" />
|
||||
@ -126,7 +127,7 @@
|
||||
<Compile Include="TestProvider.cs" />
|
||||
<Compile Include="AuthenticationBootstrapper.cs" />
|
||||
<Compile Include="ConfigFilePathProvider.cs" />
|
||||
<Compile Include="Extensions\Notifications\ContainerHelper.cs" />
|
||||
<Compile Include="Extensions\ContainerHelper.cs" />
|
||||
<Compile Include="Extensions\Notifications\NotificationManager.cs" />
|
||||
<Compile Include="Modules\HistoryModule.cs" />
|
||||
<Compile Include="ApiControllers\InfoApiModule.cs" />
|
||||
|
||||
@ -15,7 +15,7 @@ namespace UdpNotifier
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public INotifierProvider CreateProvider()
|
||||
public INotifierProvider GetProvider()
|
||||
{
|
||||
return new UdpNotifierProvider(_logger);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user