Skip to content

Commit

Permalink
Switch HubFactory to use Transients
Browse files Browse the repository at this point in the history
- ActivatorUtilities is just creating an object instace
  while using Transients will keep the object in the DI
  container until the scope is discarded
- Externalize Hub Configuration from constructor

#41 non-breaking
  • Loading branch information
tthiery committed Aug 1, 2020
1 parent 46c1cb9 commit 3a4f709
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 17 deletions.
12 changes: 7 additions & 5 deletions src/SharpBrick.PoweredUp/Hubs/Hub.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@
using System.Reactive.Disposables;
using System.Reactive.Linq;
using System.Threading.Tasks;
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 @@ -18,13 +16,12 @@ public abstract partial class Hub : IDisposable
private readonly IDeviceFactory _deviceFactory;

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

public Hub(byte hubId, IPoweredUpProtocol protocol, IDeviceFactory deviceFactory, ILogger<Hub> logger, IServiceProvider serviceProvider, Port[] knownPorts)
public Hub(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));
Expand All @@ -37,6 +34,11 @@ public Hub(byte hubId, IPoweredUpProtocol protocol, IDeviceFactory deviceFactory
SetupHubPropertyObservable(Protocol.UpstreamMessages);
}

public void Configure(byte hubId)
{
HubId = hubId;
}

#region Disposable Pattern
~Hub() => Dispose(false);

Expand Down
30 changes: 21 additions & 9 deletions src/SharpBrick.PoweredUp/Hubs/HubFactory.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using Microsoft.Extensions.DependencyInjection;
using SharpBrick.PoweredUp.Bluetooth;

namespace SharpBrick.PoweredUp.Hubs
Expand All @@ -14,21 +13,34 @@ public HubFactory(IServiceProvider serviceProvider)
}

public Hub CreateByBluetoothManufacturerData(byte[] manufacturerData)
=> (manufacturerData == null || manufacturerData.Length < 3) ? null : Create(GetSystemTypeFromManufacturerData((PoweredUpHubManufacturerData)manufacturerData[1]));
{
var hub = (manufacturerData == null || manufacturerData.Length < 3) ? null : Create(GetTypeFromSystemType(GetSystemTypeFromManufacturerData((PoweredUpHubManufacturerData)manufacturerData[1])));
hub.Configure(0x00);

return hub;
}

public THub Create<THub>() where THub : Hub
{
var hub = Create(typeof(THub)) as THub;
hub.Configure(0x00);

return hub;
}

private Hub Create(Type type)
=> _serviceProvider.GetService(type) as Hub ?? throw new NotSupportedException($"Hub with type {type} not registered in service locator supported.");

private SystemType GetSystemTypeFromManufacturerData(PoweredUpHubManufacturerData poweredUpHubManufacturerData)
=> (SystemType)poweredUpHubManufacturerData;

public Hub Create(SystemType hubType)
=> hubType switch
public static Type GetTypeFromSystemType(SystemType systemType)
=> systemType switch
{
SystemType.LegoTechnic_MediumHub => ActivatorUtilities.CreateInstance<TechnicMediumHub>(_serviceProvider, (byte)0x00),
_ => throw new NotSupportedException($"Hub with type {hubType} not yet supported."),
SystemType.LegoTechnic_MediumHub => typeof(TechnicMediumHub),
_ => throw new NotSupportedException(),
};

public THub Create<THub>() where THub : class
=> Create(GetSystemTypeFromType(typeof(THub))) as THub;

public static SystemType GetSystemTypeFromType(Type type)
=> type.Name switch
{
Expand Down
2 changes: 1 addition & 1 deletion src/SharpBrick.PoweredUp/Hubs/IHubFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@ namespace SharpBrick.PoweredUp.Hubs
public interface IHubFactory
{
Hub CreateByBluetoothManufacturerData(byte[] manufacturerData);
THub Create<THub>() where THub : class;
THub Create<THub>() where THub : Hub;
}
}
4 changes: 2 additions & 2 deletions src/SharpBrick.PoweredUp/Hubs/TechnicMediumHub.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ namespace SharpBrick.PoweredUp
{
public class TechnicMediumHub : Hub
{
public TechnicMediumHub(byte hubId, IPoweredUpProtocol protocol, IDeviceFactory deviceFactory, ILogger<TechnicMediumHub> logger, IServiceProvider serviceProvider = default)
: base(hubId, protocol, deviceFactory, logger, serviceProvider, new Port[] {
public TechnicMediumHub(IPoweredUpProtocol protocol, IDeviceFactory deviceFactory, ILogger<TechnicMediumHub> logger, IServiceProvider serviceProvider = default)
: base(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
8 changes: 8 additions & 0 deletions src/SharpBrick.PoweredUp/IServiceCollectionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,19 @@ public static class IServiceCollectionExtensions
{
public static IServiceCollection AddPoweredUp(this IServiceCollection self)
=> self
// global infrastructure
.AddSingleton<PoweredUpHost>()

// per connection infrastructure
.AddScoped<BluetoothKernel>()
.AddScoped<IHubFactory, HubFactory>()
.AddScoped<IDeviceFactory, DeviceFactory>()
.AddScoped<IPoweredUpProtocol, PoweredUpProtocol>()

// hubs
.AddTransient<TechnicMediumHub>()

// functions
.AddTransient<LinearMidCalibration>();
}
}

0 comments on commit 3a4f709

Please sign in to comment.