Add project files.
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using TheXamlGuy.Framework.Core;
|
||||
using TheXamlGuy.Framework.Serial;
|
||||
|
||||
namespace TheXamlGuy.Framework.Microcontroller;
|
||||
|
||||
public static class IHostBuilderExtensions
|
||||
{
|
||||
public static IHostBuilder ConfigureMicrocontrollers(this IHostBuilder hostBuilder, Action<HostBuilderContext, IMicrocontrollerBuilder> builderDelegate)
|
||||
{
|
||||
hostBuilder.ConfigureServices((hostBuilderContext, serviceCollection) =>
|
||||
{
|
||||
MicrocontrollerBuilder? builder = new();
|
||||
|
||||
builderDelegate.Invoke(hostBuilderContext, builder);
|
||||
serviceCollection.TryAddSingleton<ISerialFactory, SerialFactory>();
|
||||
serviceCollection.TryAddSingleton<IMicrocontrollerFactory, MicrocontrollerFactory>();
|
||||
|
||||
foreach (IMicrocontrollerBuilderConfiguration configuration in builder.Configurations)
|
||||
{
|
||||
serviceCollection.AddSingleton(provider => configuration.Factory.Invoke(provider));
|
||||
}
|
||||
|
||||
serviceCollection.RegisterHandlers(typeof(IMicrocontrollerContext).Assembly, typeof(ISerialContext).Assembly);
|
||||
});
|
||||
|
||||
return hostBuilder;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using TheXamlGuy.Framework.Serial;
|
||||
|
||||
namespace TheXamlGuy.Framework.Microcontroller;
|
||||
|
||||
public interface IMicrocontrollerBuilder
|
||||
{
|
||||
IReadOnlyCollection<IMicrocontrollerBuilderConfiguration> Configurations { get; }
|
||||
|
||||
IMicrocontrollerBuilderConfiguration<TConfiguration, TSerialReader, TRead, TReadDeserializer> Add<TConfiguration, TSerialReader, TRead, TReadDeserializer>(IConfiguration configuration)
|
||||
where TConfiguration : IMicrocontrollerConfiguration, new()
|
||||
where TSerialReader : SerialReader<TRead> where TReadDeserializer : IMicrocontrollerModuleDeserializer<TRead>, new();
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using Microcontroller;
|
||||
using TheXamlGuy.Framework.Serial;
|
||||
|
||||
namespace TheXamlGuy.Framework.Microcontroller;
|
||||
|
||||
public interface IMicrocontrollerBuilderConfiguration
|
||||
{
|
||||
IReadOnlyCollection<IMicrocontrollerModuleDescriptor> Modules { get; }
|
||||
|
||||
Func<IServiceProvider, IMicrocontrollerContext> Factory { get; }
|
||||
}
|
||||
|
||||
public interface IMicrocontrollerBuilderConfiguration<TConfiguration, TSerialReader, TRead, TReadDeserializer> : IMicrocontrollerBuilderConfiguration where TConfiguration : IMicrocontrollerConfiguration, new()
|
||||
where TSerialReader : SerialReader<TRead> where TReadDeserializer : IMicrocontrollerModuleDeserializer<TRead>, new()
|
||||
{
|
||||
|
||||
IMicrocontrollerBuilderConfiguration<TConfiguration, TSerialReader, TRead, TReadDeserializer> AddModule<TModule>() where TModule : IMicrocontrollerModule, new();
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
using TheXamlGuy.Framework.Serial;
|
||||
|
||||
namespace TheXamlGuy.Framework.Microcontroller;
|
||||
|
||||
public interface IMicrocontrollerConfiguration : ISerialConfiguration
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
using TheXamlGuy.Framework.Core;
|
||||
|
||||
namespace TheXamlGuy.Framework.Microcontroller;
|
||||
|
||||
public interface IMicrocontrollerContext : IInitializer
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public interface IMicrocontrollerContext<TRead, TModuleDeserializer> : IMicrocontrollerContext where TModuleDeserializer : IMicrocontrollerModuleDeserializer<TRead>, new()
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
using TheXamlGuy.Framework.Serial;
|
||||
|
||||
namespace TheXamlGuy.Framework.Microcontroller;
|
||||
|
||||
public interface IMicrocontrollerFactory
|
||||
{
|
||||
IMicrocontrollerContext<TRead, TReadDeserializer> Create<TSerialReader, TRead, TReadDeserializer>(IMicrocontrollerConfiguration configuration, IReadOnlyCollection<IMicrocontrollerModuleDescriptor> modules) where TSerialReader : SerialReader<TRead> where TReadDeserializer : IMicrocontrollerModuleDeserializer<TRead>, new();
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace Microcontroller
|
||||
{
|
||||
public interface IMicrocontrollerModule
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using Microcontroller;
|
||||
|
||||
namespace TheXamlGuy.Framework.Microcontroller;
|
||||
|
||||
public interface IMicrocontrollerModuleDescriptor<TModule> : IMicrocontrollerModuleDescriptor where TModule : IMicrocontrollerModule
|
||||
{
|
||||
Func<TModule>? Factory { get; }
|
||||
}
|
||||
|
||||
public interface IMicrocontrollerModuleDescriptor
|
||||
{
|
||||
Type Type { get; }
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace TheXamlGuy.Framework.Microcontroller;
|
||||
|
||||
public interface IMicrocontrollerModuleDeserializer<TRead>
|
||||
{
|
||||
public TRead? Read { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="7.0.0-rc.2.22472.3" />
|
||||
<PackageReference Include="Microsoft.Extensions.Options" Version="7.0.0-rc.2.22472.3" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Core\Core.csproj" />
|
||||
<ProjectReference Include="..\Serial\Serial.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,23 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using System.Collections.ObjectModel;
|
||||
using TheXamlGuy.Framework.Serial;
|
||||
|
||||
namespace TheXamlGuy.Framework.Microcontroller;
|
||||
|
||||
public class MicrocontrollerBuilder : IMicrocontrollerBuilder
|
||||
{
|
||||
private readonly List<IMicrocontrollerBuilderConfiguration> configurations = new();
|
||||
|
||||
public IReadOnlyCollection<IMicrocontrollerBuilderConfiguration> Configurations => new ReadOnlyCollection<IMicrocontrollerBuilderConfiguration>(configurations);
|
||||
|
||||
public IMicrocontrollerBuilderConfiguration<TConfiguration, TSerialReader, TRead, TReadDeserializer> Add<TConfiguration, TSerialReader, TRead, TReadDeserializer>(IConfiguration configuration)
|
||||
where TConfiguration : IMicrocontrollerConfiguration, new()
|
||||
where TSerialReader : SerialReader<TRead>
|
||||
where TReadDeserializer : IMicrocontrollerModuleDeserializer<TRead>, new()
|
||||
{
|
||||
MicrocontrollerBuilderConfiguration<TConfiguration, TSerialReader, TRead, TReadDeserializer>? builderConfiguration = new(configuration);
|
||||
configurations.Add(builderConfiguration);
|
||||
|
||||
return builderConfiguration;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
using Microcontroller;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System.Collections.ObjectModel;
|
||||
using TheXamlGuy.Framework.Serial;
|
||||
|
||||
namespace TheXamlGuy.Framework.Microcontroller;
|
||||
|
||||
public class MicrocontrollerBuilderConfiguration<TConfiguration, TSerialReader, TRead, TReadDeserializer> : IMicrocontrollerBuilderConfiguration<TConfiguration, TSerialReader, TRead, TReadDeserializer> where TConfiguration : IMicrocontrollerConfiguration, new()
|
||||
where TSerialReader : SerialReader<TRead> where TReadDeserializer : IMicrocontrollerModuleDeserializer<TRead>, new()
|
||||
{
|
||||
public MicrocontrollerBuilderConfiguration(IConfiguration configuration)
|
||||
{
|
||||
this.configuration = configuration;
|
||||
}
|
||||
|
||||
private readonly List<IMicrocontrollerModuleDescriptor> modules = new();
|
||||
private readonly IConfiguration configuration;
|
||||
|
||||
public Func<IServiceProvider, IMicrocontrollerContext> Factory => (IServiceProvider provider) => provider.GetService<IMicrocontrollerFactory>()!.Create<TSerialReader, TRead, TReadDeserializer>(configuration.Get<TConfiguration>(), Modules);
|
||||
|
||||
public IReadOnlyCollection<IMicrocontrollerModuleDescriptor> Modules => new ReadOnlyCollection<IMicrocontrollerModuleDescriptor>(modules);
|
||||
|
||||
public IMicrocontrollerBuilderConfiguration<TConfiguration, TSerialReader, TRead, TReadDeserializer> AddModule<TModule>() where TModule : IMicrocontrollerModule, new()
|
||||
{
|
||||
modules.Add(new MicrocontrollerModuleDescriptor<TModule>());
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace TheXamlGuy.Framework.Microcontroller;
|
||||
|
||||
public class MicrocontrollerConfiguration : IMicrocontrollerConfiguration
|
||||
{
|
||||
[NotNull]
|
||||
public string? PortName { get; set; }
|
||||
|
||||
public int BaudRate { get; set; }
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
using Microcontroller;
|
||||
using TheXamlGuy.Framework.Core;
|
||||
using TheXamlGuy.Framework.Serial;
|
||||
|
||||
namespace TheXamlGuy.Framework.Microcontroller;
|
||||
|
||||
public class MicrocontrollerContext<TRead, TReadDeserializer> : IMicrocontrollerContext<TRead, TReadDeserializer> where TReadDeserializer : IMicrocontrollerModuleDeserializer<TRead>, new()
|
||||
{
|
||||
private readonly IReadOnlyCollection<IMicrocontrollerModuleDescriptor> modules;
|
||||
private readonly IEventAggregator eventAggregator;
|
||||
private readonly IMediator mediator;
|
||||
private readonly ISerialContext serialContext;
|
||||
|
||||
public MicrocontrollerContext(IReadOnlyCollection<IMicrocontrollerModuleDescriptor> modules,
|
||||
IEventAggregator eventAggregator,
|
||||
IMediator mediator,
|
||||
ISerialContext serialContext)
|
||||
{
|
||||
this.modules = modules;
|
||||
this.eventAggregator = eventAggregator;
|
||||
this.mediator = mediator;
|
||||
this.serialContext = serialContext;
|
||||
}
|
||||
|
||||
public async Task InitializeAsync()
|
||||
{
|
||||
eventAggregator.Subscribe<SerialResponse<TRead>>(OnEvent, null, args => args.Context.Equals(serialContext));
|
||||
serialContext.Open();
|
||||
|
||||
await Task.CompletedTask;
|
||||
}
|
||||
|
||||
private async void OnEvent(SerialResponse<TRead> args)
|
||||
{
|
||||
IMicrocontrollerModule? module = await mediator.HandleAsync<IMicrocontrollerModule>(new TReadDeserializer { Read = args.Content }, modules);
|
||||
eventAggregator.Publish((dynamic?)module);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
using TheXamlGuy.Framework.Core;
|
||||
using TheXamlGuy.Framework.Serial;
|
||||
|
||||
namespace TheXamlGuy.Framework.Microcontroller;
|
||||
|
||||
public class MicrocontrollerFactory : IMicrocontrollerFactory
|
||||
{
|
||||
private readonly IServiceFactory factory;
|
||||
private readonly ISerialFactory serialFactory;
|
||||
private readonly Dictionary<ISerialConfiguration, IMicrocontrollerContext> cache = new();
|
||||
|
||||
public MicrocontrollerFactory(IServiceFactory factory,
|
||||
ISerialFactory serialFactory)
|
||||
{
|
||||
this.factory = factory;
|
||||
this.serialFactory = serialFactory;
|
||||
}
|
||||
|
||||
public IMicrocontrollerContext<TRead, TReadDeserializer> Create<TSerialReader, TRead, TReadDeserializer>(IMicrocontrollerConfiguration configuration, IReadOnlyCollection<IMicrocontrollerModuleDescriptor> modules) where TSerialReader : SerialReader<TRead> where TReadDeserializer : IMicrocontrollerModuleDeserializer<TRead>, new()
|
||||
{
|
||||
if (cache.TryGetValue(configuration, out IMicrocontrollerContext? context))
|
||||
{
|
||||
return (IMicrocontrollerContext<TRead, TReadDeserializer>)context;
|
||||
}
|
||||
|
||||
ISerialContext<TSerialReader, TRead> serialContext = serialFactory.Create<TSerialReader, TRead>(configuration);
|
||||
|
||||
context = factory.Create<MicrocontrollerContext<TRead, TReadDeserializer>>(modules, serialContext);
|
||||
cache.Add(configuration, context);
|
||||
|
||||
return (IMicrocontrollerContext<TRead, TReadDeserializer>)context;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
using Microcontroller;
|
||||
|
||||
namespace TheXamlGuy.Framework.Microcontroller;
|
||||
|
||||
public record MicrocontrollerModuleDescriptor<TModule> : IMicrocontrollerModuleDescriptor<TModule> where TModule : IMicrocontrollerModule, new()
|
||||
{
|
||||
public Type Type => typeof(TModule);
|
||||
|
||||
public Func<TModule>? Factory => new(() => new TModule());
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace TheXamlGuy.Framework.Microcontroller;
|
||||
|
||||
|
||||
public abstract record MicrocontrollerModuleDeserializer<TRead> : IMicrocontrollerModuleDeserializer<TRead>
|
||||
{
|
||||
public TRead? Read { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
using Microcontroller;
|
||||
using TheXamlGuy.Framework.Core;
|
||||
|
||||
namespace TheXamlGuy.Framework.Microcontroller;
|
||||
|
||||
public abstract class MicrocontrollerModuleDeserializerHandler<TDeserializer, TRead> : IMediatorAsyncHandler<IMicrocontrollerModule?, TDeserializer> where TDeserializer : MicrocontrollerModuleDeserializer<TRead>
|
||||
{
|
||||
public MicrocontrollerModuleDeserializerHandler(IReadOnlyCollection<IMicrocontrollerModuleDescriptor> modules)
|
||||
{
|
||||
Modules = modules;
|
||||
}
|
||||
|
||||
public IReadOnlyCollection<IMicrocontrollerModuleDescriptor> Modules { get; }
|
||||
|
||||
public abstract Task<IMicrocontrollerModule?> Handle(TDeserializer request, CancellationToken cancellationToken = default);
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace TheXamlGuy.Framework.Microcontroller;
|
||||
|
||||
public record MicrocontrollerModuleJsonDeserializer : MicrocontrollerModuleDeserializer<string>
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
using Microcontroller;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Nodes;
|
||||
|
||||
namespace TheXamlGuy.Framework.Microcontroller;
|
||||
|
||||
public class MicrocontrollerModuleJsonDeserializerHandler : MicrocontrollerModuleDeserializerHandler<MicrocontrollerModuleJsonDeserializer, string>
|
||||
{
|
||||
public MicrocontrollerModuleJsonDeserializerHandler(IReadOnlyCollection<IMicrocontrollerModuleDescriptor> modules) : base(modules)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override async Task<IMicrocontrollerModule?> Handle(MicrocontrollerModuleJsonDeserializer request, CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (JsonNode.Parse(request.Read!) is JsonNode body)
|
||||
{
|
||||
if (body["module"] is JsonNode triggerNode)
|
||||
{
|
||||
if (triggerNode["type"] is JsonNode typeNode)
|
||||
{
|
||||
if (Modules.FirstOrDefault(x => x.Type.Name.Equals(typeNode.GetValue<string>(), StringComparison.InvariantCultureIgnoreCase)) is IMicrocontrollerModuleDescriptor descriptor)
|
||||
{
|
||||
if (triggerNode["parameters"] is JsonNode parametersNode)
|
||||
{
|
||||
return (IMicrocontrollerModule?)parametersNode.Deserialize(descriptor.Type, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
|
||||
}
|
||||
else
|
||||
{
|
||||
return (IMicrocontrollerModule?)Activator.CreateInstance(descriptor.Type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return await Task.FromResult<IMicrocontrollerModule?>(default);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
using Microcontroller;
|
||||
using TheXamlGuy.Framework.Core;
|
||||
|
||||
namespace TheXamlGuy.Framework.Microcontroller;
|
||||
|
||||
public record CapactiveSensor : IMicrocontrollerModule, ITwoStateSensor, IHasSensorPlacement
|
||||
{
|
||||
public SensorState State { get; init; }
|
||||
|
||||
public SensorPlacement Placement { get; init; }
|
||||
}
|
||||
Reference in New Issue
Block a user