Skip to content

Commit

Permalink
Remove ServiceProvider usage from Hub
Browse files Browse the repository at this point in the history
- Add constructor for IDeviceFactory
- Moved PoweredUpProtocol creation into the DI + Host
- Moved BluetoothKernel creation into the DI

#46 non-breaking (all types internal)
  • Loading branch information
tthiery committed Aug 1, 2020
1 parent 0b0406e commit 46c1cb9
Show file tree
Hide file tree
Showing 8 changed files with 54 additions and 39 deletions.
6 changes: 3 additions & 3 deletions src/SharpBrick.PoweredUp.Cli/Commands/DevicesList.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ public static async Task ExecuteAsync(ILoggerFactory loggerFactory, WinRTPowered
.AddSingleton<ILoggerFactory>(loggerFactory)
.BuildServiceProvider();

using (var protocol = new PoweredUpProtocol(
new BluetoothKernel(poweredUpBluetoothAdapter, bluetoothAddress, loggerFactory.CreateLogger<BluetoothKernel>()),
serviceProvider))
using (var kernel = new BluetoothKernel(poweredUpBluetoothAdapter, loggerFactory.CreateLogger<BluetoothKernel>()))
using (var protocol = new PoweredUpProtocol(kernel, serviceProvider))
{
kernel.BluetoothAddress = bluetoothAddress;
var discoverPorts = new DiscoverPorts(protocol, logger: loggerFactory.CreateLogger<DiscoverPorts>()); // register to upstream

if (enableTrace)
Expand Down
7 changes: 4 additions & 3 deletions src/SharpBrick.PoweredUp.Cli/Commands/DumpStaticPortInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,11 @@ public static async Task ExecuteAsync(ILoggerFactory loggerFactory, WinRTPowered
.AddSingleton<ILoggerFactory>(loggerFactory)
.BuildServiceProvider();

using (var protocol = new PoweredUpProtocol(
new BluetoothKernel(poweredUpBluetoothAdapter, bluetoothAddress, loggerFactory.CreateLogger<BluetoothKernel>()),
serviceProvider))

using (var kernel = new BluetoothKernel(poweredUpBluetoothAdapter, loggerFactory.CreateLogger<BluetoothKernel>()))
using (var protocol = new PoweredUpProtocol(kernel, serviceProvider))
{
kernel.BluetoothAddress = bluetoothAddress;
var discoverPorts = new DiscoverPorts(protocol, logger: loggerFactory.CreateLogger<DiscoverPorts>());

if (enableTrace)
Expand Down
7 changes: 3 additions & 4 deletions src/SharpBrick.PoweredUp/Bluetooth/BluetoothKernel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,22 @@ public class BluetoothKernel : IDisposable
{
private readonly ILogger _logger;
private readonly IPoweredUpBluetoothAdapter _bluetoothAdapter;
private readonly ulong _bluetoothAddress;
public ulong BluetoothAddress { get; set; }
private IPoweredUpBluetoothDevice _device = null;
private IPoweredUpBluetoothService _service = null;
private IPoweredUpBluetoothCharacteristic _characteristic = null;

public BluetoothKernel(IPoweredUpBluetoothAdapter bluetoothAdapter, ulong bluetoothAddress, ILogger<BluetoothKernel> logger = default)
public BluetoothKernel(IPoweredUpBluetoothAdapter bluetoothAdapter, ILogger<BluetoothKernel> logger = default)
{
_bluetoothAdapter = bluetoothAdapter ?? throw new ArgumentNullException(nameof(bluetoothAdapter));
_bluetoothAddress = bluetoothAddress;
_logger = logger;
}

public bool IsConnected => _characteristic != null;

public async Task ConnectAsync()
{
_device = await _bluetoothAdapter.GetDeviceAsync(_bluetoothAddress);
_device = await _bluetoothAdapter.GetDeviceAsync(BluetoothAddress);
_service = await _device.GetServiceAsync(new Guid(PoweredUpBluetoothConstants.LegoHubService));
_characteristic = await _service.GetCharacteristicAsync(new Guid(PoweredUpBluetoothConstants.LegoHubCharacteristic));

Expand Down
17 changes: 6 additions & 11 deletions src/SharpBrick.PoweredUp/Hubs/Hub.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using SharpBrick.PoweredUp.Bluetooth;
using SharpBrick.PoweredUp.Devices;
using SharpBrick.PoweredUp.Protocol;
using SharpBrick.PoweredUp.Protocol.Messages;

Expand All @@ -14,27 +15,21 @@ public abstract partial class Hub : IDisposable
{
private CompositeDisposable _compositeDisposable = new CompositeDisposable();
private readonly ILogger _logger;
private readonly IDeviceFactory _deviceFactory;

public IPoweredUpProtocol Protocol { get; private set; }
public byte HubId { get; }
public IServiceProvider ServiceProvider { get; }
public bool IsConnected => Protocol != null;

public Hub(byte hubId, IServiceProvider serviceProvider, Port[] knownPorts)
public Hub(byte hubId, IPoweredUpProtocol protocol, IDeviceFactory deviceFactory, ILogger<Hub> logger, IServiceProvider serviceProvider, Port[] knownPorts)
{
HubId = hubId;
Protocol = protocol ?? throw new ArgumentNullException(nameof(protocol));
_deviceFactory = deviceFactory ?? throw new ArgumentNullException(nameof(deviceFactory));
ServiceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider));
AddKnownPorts(knownPorts ?? throw new ArgumentNullException(nameof(knownPorts)));
_logger = serviceProvider.GetService<ILoggerFactory>().CreateLogger<Hub>();

}

public void ConnectWithBluetoothAdapter(IPoweredUpBluetoothAdapter poweredUpBluetoothAdapter, ulong bluetoothAddress)
{
_logger?.LogDebug("Init Hub with BluetoothKernel");
var kernel = ActivatorUtilities.CreateInstance<BluetoothKernel>(ServiceProvider, poweredUpBluetoothAdapter, bluetoothAddress);
_logger?.LogDebug("Init Hub with PoweredUpProtocol");
Protocol = ActivatorUtilities.CreateInstance<PoweredUpProtocol>(ServiceProvider, kernel);
_logger = logger;

SetupOnHubChange();
SetupOnPortChangeObservable(Protocol.UpstreamMessages);
Expand Down
10 changes: 2 additions & 8 deletions src/SharpBrick.PoweredUp/Hubs/Hub_Ports.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
using System.Linq;
using System.Reactive.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using SharpBrick.PoweredUp.Devices;
using SharpBrick.PoweredUp.Protocol;
using SharpBrick.PoweredUp.Protocol.Messages;

Expand Down Expand Up @@ -114,9 +112,7 @@ private void OnHubAttachedIOMessage(HubAttachedIOMessage hubAttachedIO)
case HubAttachedIOForAttachedDeviceMessage attachedDeviceMessage:
port = Port(attachedDeviceMessage.PortId);

var deviceFactory = ServiceProvider.GetService<IDeviceFactory>();

var device = deviceFactory.CreateConnected(attachedDeviceMessage.IOTypeId, Protocol, attachedDeviceMessage.HubId, attachedDeviceMessage.PortId);
var device = _deviceFactory.CreateConnected(attachedDeviceMessage.IOTypeId, Protocol, attachedDeviceMessage.HubId, attachedDeviceMessage.PortId);

port.AttachDevice(device, attachedDeviceMessage.IOTypeId);
break;
Expand Down Expand Up @@ -144,9 +140,7 @@ private Port OnHubAttachedVirtualIOMessage(HubAttachedIOForAttachedVirtualDevice

_ports[createdVirtualPort.PortId] = createdVirtualPort;

var deviceFactory = ServiceProvider.GetService<IDeviceFactory>();

var deviceOnVirtualPort = deviceFactory.CreateConnected(attachedVirtualDeviceMessage.IOTypeId, Protocol, attachedVirtualDeviceMessage.HubId, attachedVirtualDeviceMessage.PortId);
var deviceOnVirtualPort = _deviceFactory.CreateConnected(attachedVirtualDeviceMessage.IOTypeId, Protocol, attachedVirtualDeviceMessage.HubId, attachedVirtualDeviceMessage.PortId);

createdVirtualPort.AttachDevice(deviceOnVirtualPort, attachedVirtualDeviceMessage.IOTypeId);

Expand Down
7 changes: 5 additions & 2 deletions src/SharpBrick.PoweredUp/Hubs/TechnicMediumHub.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
using System;
using Microsoft.Extensions.Logging;
using SharpBrick.PoweredUp.Devices;
using SharpBrick.PoweredUp.Protocol;

namespace SharpBrick.PoweredUp
{
public class TechnicMediumHub : Hub
{
public TechnicMediumHub(byte hubId, IServiceProvider serviceProvider = default)
: base(hubId, serviceProvider, new Port[] {
public TechnicMediumHub(byte hubId, IPoweredUpProtocol protocol, IDeviceFactory deviceFactory, ILogger<TechnicMediumHub> logger, IServiceProvider serviceProvider = default)
: base(hubId, protocol, deviceFactory, logger, serviceProvider, new Port[] {
new Port(0, nameof(A), true),
new Port(1, nameof(B), true),
new Port(2, nameof(C), true),
Expand Down
4 changes: 4 additions & 0 deletions src/SharpBrick.PoweredUp/IServiceCollectionExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
using Microsoft.Extensions.DependencyInjection;
using SharpBrick.PoweredUp.Bluetooth;
using SharpBrick.PoweredUp.Devices;
using SharpBrick.PoweredUp.Functions;
using SharpBrick.PoweredUp.Hubs;
using SharpBrick.PoweredUp.Protocol;

namespace SharpBrick.PoweredUp
{
Expand All @@ -10,8 +12,10 @@ public static class IServiceCollectionExtensions
public static IServiceCollection AddPoweredUp(this IServiceCollection self)
=> self
.AddSingleton<PoweredUpHost>()
.AddScoped<BluetoothKernel>()
.AddScoped<IHubFactory, HubFactory>()
.AddScoped<IDeviceFactory, DeviceFactory>()
.AddScoped<IPoweredUpProtocol, PoweredUpProtocol>()
.AddTransient<LinearMidCalibration>();
}
}
35 changes: 27 additions & 8 deletions src/SharpBrick.PoweredUp/PoweredUpHost.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,24 @@ public void Discover(Func<Hub, Task> onDiscovery, CancellationToken token = defa
{
_bluetoothAdapter.Discover(deviceInfo =>
{
if (!_hubs.Any(i => i.Item1.BluetoothAddress == deviceInfo.BluetoothAddress))
try
{
var hub = CreateProtocolScope(deviceInfo.BluetoothAddress, hubFactory => hubFactory.CreateByBluetoothManufacturerData(deviceInfo.ManufacturerData));
if (!_hubs.Any(i => i.Item1.BluetoothAddress == deviceInfo.BluetoothAddress))
{
var hub = CreateHubInBluetoothScope(deviceInfo.BluetoothAddress, hubFactory => hubFactory.CreateByBluetoothManufacturerData(deviceInfo.ManufacturerData));
_hubs.Add((deviceInfo, hub));
_hubs.Add((deviceInfo, hub));
_logger.LogInformation($"Discovered log of type {hub.GetType().Name} with name '{deviceInfo.Name}' on Bluetooth Address '{deviceInfo.BluetoothAddress}'");
_logger.LogInformation($"Discovered log of type {hub.GetType().Name} with name '{deviceInfo.Name}' on Bluetooth Address '{deviceInfo.BluetoothAddress}'");
onDiscovery(hub).Wait();
onDiscovery(hub).Wait();
}
}
catch (Exception e)
{
_logger.LogError(e, $"Exception discovery handler within {nameof(Discover)}");
throw;
}
}, token);
}
Expand Down Expand Up @@ -80,7 +89,7 @@ public async Task<THub> DiscoverAsync<THub>(CancellationToken token = default)

public THub Create<THub>(ulong bluetoothAddress) where THub : Hub
{
var hub = CreateProtocolScope(bluetoothAddress, hubFactory => hubFactory.Create<THub>());
var hub = CreateHubInBluetoothScope(bluetoothAddress, hubFactory => hubFactory.Create<THub>());

_hubs.Add((new PoweredUpBluetoothDeviceInfo()
{
Expand All @@ -92,14 +101,24 @@ public THub Create<THub>(ulong bluetoothAddress) where THub : Hub
return hub;
}

private THub CreateProtocolScope<THub>(ulong bluetoothAddress, Func<IHubFactory, THub> factory) where THub : Hub
private IServiceProvider CreateBluetoothScope(ulong bluetoothAddress)
{
var scopedServiceProvider = ServiceProvider.CreateScope().ServiceProvider;

// initialize scoped bluetooth kernel to bluetooth address.
var kernel = scopedServiceProvider.GetService<BluetoothKernel>();
kernel.BluetoothAddress = bluetoothAddress;

return scopedServiceProvider;
}

private THub CreateHubInBluetoothScope<THub>(ulong bluetoothAddress, Func<IHubFactory, THub> factory) where THub : Hub
{
var scopedServiceProvider = CreateBluetoothScope(bluetoothAddress);

var hubFactory = scopedServiceProvider.GetService<IHubFactory>();

var hub = factory(hubFactory);
hub.ConnectWithBluetoothAdapter(_bluetoothAdapter, bluetoothAddress);

return hub;
}
Expand Down

0 comments on commit 46c1cb9

Please sign in to comment.