Skip to content

Commit

Permalink
Well.. might as well make everything autofac
Browse files Browse the repository at this point in the history
  • Loading branch information
asdacap committed Sep 27, 2024
1 parent fd8845e commit 1c54c1d
Show file tree
Hide file tree
Showing 13 changed files with 54 additions and 89 deletions.
5 changes: 3 additions & 2 deletions src/Nethermind/Nethermind.Api/IApiWithBlockchain.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// SPDX-License-Identifier: LGPL-3.0-only

#nullable enable
using Autofac;
using Microsoft.Extensions.DependencyInjection;
using Nethermind.Blockchain;
using Nethermind.Blockchain.Filters;
Expand Down Expand Up @@ -101,9 +102,9 @@ public interface IApiWithBlockchain : IApiWithStores, IBlockchainBridgeFactory
BackgroundTaskScheduler BackgroundTaskScheduler { get; set; }
CensorshipDetector CensorshipDetector { get; set; }

public IServiceCollection CreateServiceCollectionFromApiWithBlockchain(IServiceCollection serviceCollection)
public ContainerBuilder CreateServiceCollectionFromApiWithBlockchain(ContainerBuilder builder)
{
return CreateServiceCollectionFromApiWithStores(serviceCollection)
return CreateServiceCollectionFromApiWithStores(builder)
.AddPropertiesFrom<IApiWithBlockchain>(this)
.AddSingleton<INodeStorage>(NodeStorageFactory.WrapKeyValueStore(DbProvider!.StateDb));

Expand Down
4 changes: 2 additions & 2 deletions src/Nethermind/Nethermind.Api/IApiWithNetwork.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,9 @@ public interface IApiWithNetwork : IApiWithBlockchain

IContainer? ApiWithNetworkServiceContainer { get; set; }

public IServiceCollection CreateServiceCollectionFromApiWithNetwork(IServiceCollection serviceCollection)
public ContainerBuilder CreateServiceCollectionFromApiWithNetwork(ContainerBuilder builder)
{
return CreateServiceCollectionFromApiWithBlockchain(serviceCollection)
return CreateServiceCollectionFromApiWithBlockchain(builder)
.AddPropertiesFrom(this);
}
}
Expand Down
5 changes: 3 additions & 2 deletions src/Nethermind/Nethermind.Api/IApiWithStores.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited
// SPDX-License-Identifier: LGPL-3.0-only

using Autofac;
using Microsoft.Extensions.DependencyInjection;
using Nethermind.Blockchain;
using Nethermind.Blockchain.Blocks;
Expand Down Expand Up @@ -32,9 +33,9 @@ public interface IApiWithStores : IBasicApi
IWallet? Wallet { get; set; }
IBlockStore? BadBlocksStore { get; set; }

public IServiceCollection CreateServiceCollectionFromApiWithStores(IServiceCollection serviceCollection)
public ContainerBuilder CreateServiceCollectionFromApiWithStores(ContainerBuilder builder)
{
return CreateServiceCollectionFromBasicApi(serviceCollection)
return CreateServiceCollectionFromBasicApi(builder)
.AddPropertiesFrom<IApiWithStores>(this);
}
}
Expand Down
9 changes: 5 additions & 4 deletions src/Nethermind/Nethermind.Api/IBasicApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Collections.Generic;
using System.IO.Abstractions;
using System.Linq;
using Autofac;
using Microsoft.Extensions.DependencyInjection;
using Nethermind.Abi;
using Nethermind.Api.Extensions;
Expand Down Expand Up @@ -60,15 +61,15 @@ public IEnumerable<IConsensusWrapperPlugin> GetConsensusWrapperPlugins() =>
public IEnumerable<ISynchronizationPlugin> GetSynchronizationPlugins() =>
Plugins.OfType<ISynchronizationPlugin>();

public IServiceCollection CreateServiceCollectionFromBasicApi(IServiceCollection serviceCollection)
public ContainerBuilder CreateServiceCollectionFromBasicApi(ContainerBuilder builder)
{
IServiceCollection sc = serviceCollection
builder
.AddPropertiesFrom<IBasicApi>(this)
.AddSingleton(ConfigProvider.GetConfig<ISyncConfig>());

DbProvider!.ConfigureServiceCollection(sc);
DbProvider!.ConfigureServiceCollection(builder);

return sc;
return builder;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// SPDX-License-Identifier: LGPL-3.0-only

using System;
using Autofac;
using FluentAssertions;
using Microsoft.Extensions.DependencyInjection;
using NUnit.Framework;
Expand All @@ -14,35 +15,14 @@ public class ServiceCollectionExtensionsTests
public void AddPropertiesFrom_CanAddProperties()
{
ITestInterface interfaceImplementation = new InterfaceImplementation();
IServiceProvider sp = new ServiceCollection()
IContainer sp = new ContainerBuilder()
.AddPropertiesFrom(interfaceImplementation)
.BuildServiceProvider();
.Build();

sp.GetService<DeclaredService>().Should().NotBeNull();
sp.GetService<DeclaredInBase>().Should().BeNull();
sp.GetService<Ignored>().Should().BeNull();
sp.GetService<DeclaredButNullService>().Should().BeNull();
}

[Test]
public void TestForwardDependency_ShouldNotDispose()
{
ServiceProvider sp1 = new ServiceCollection()
.AddSingleton<DisposableService>()
.BuildServiceProvider();

ServiceProvider sp2 = new ServiceCollection()
.ForwardServiceAsSingleton<DisposableService>(sp1)
.BuildServiceProvider();

DisposableService disposableService = sp2.GetRequiredService<DisposableService>();
disposableService.WasDisposed.Should().BeFalse();

sp2.Dispose();
disposableService.WasDisposed.Should().BeFalse();

sp1.Dispose();
disposableService.WasDisposed.Should().BeTrue();
sp.Resolve<DeclaredService>().Should().NotBeNull();
sp.Resolve<DeclaredInBase>().Should().BeNull();
sp.Resolve<Ignored>().Should().BeNull();
sp.Resolve<DeclaredButNullService>().Should().BeNull();
}

private class InterfaceImplementation : ITestInterface
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,32 +7,11 @@
using System.Reflection;
using Autofac;
using Autofac.Features.AttributeFilters;
using Microsoft.Extensions.DependencyInjection;

namespace Nethermind.Core;

public static class IServiceCollectionExtensions
public static class ContainerBuilderExtensions
{
public static IServiceCollection ForwardServiceAsSingleton<T>(this IServiceCollection configuration, IServiceProvider baseServiceProvider) where T : class
{
T? theService = baseServiceProvider.GetService<T>();
if (theService != null)
{
configuration.AddSingleton(baseServiceProvider.GetRequiredService<T>());
}
else
{
// It could be that this is in a test where the service was not registered and any dependency will be
// replaced anyway. While using a factory function like this seems like it would have the same behaviour
// as getting it directly first, it has one critical difference. When the final IServiceProvider is
// disposed, it would also call the Dispose function of the service as it assume that it created and
// therefore owned the service.
configuration.AddSingleton((sp) => baseServiceProvider.GetRequiredService<T>());
}

return configuration;
}

/// <summary>
/// Add all properties as singleton. It get them ahead of time instead of lazily to prevent the final service provider
/// from disposing it. To prevent a property from being included, use <see cref="SkipServiceCollectionAttribute"/>.
Expand All @@ -41,7 +20,7 @@ public static IServiceCollection ForwardServiceAsSingleton<T>(this IServiceColle
/// <param name="source"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public static IServiceCollection AddPropertiesFrom<T>(this IServiceCollection configuration, T source) where T : class
public static ContainerBuilder AddPropertiesFrom<T>(this ContainerBuilder configuration, T source) where T : class
{
Type t = typeof(T);

Expand All @@ -54,7 +33,7 @@ public static IServiceCollection AddPropertiesFrom<T>(this IServiceCollection co
object? val = propertyInfo.GetValue(source);
if (val != null)
{
configuration = configuration.AddSingleton(propertyInfo.PropertyType, val);
configuration.RegisterInstance(val).As(propertyInfo.PropertyType);
}
}

Expand Down Expand Up @@ -91,6 +70,15 @@ public static ContainerBuilder AddSingleton<T, TImpl>(this ContainerBuilder buil
return builder;
}

public static ContainerBuilder AddKeyedSingleton<T>(this ContainerBuilder builder, string key, T instance) where T : class
{
builder.RegisterInstance(instance)
.Named<T>(key)
.SingleInstance();

return builder;
}

public static ContainerBuilder AddScoped<T>(this ContainerBuilder builder) where T : notnull
{
builder.RegisterType<T>()
Expand Down
4 changes: 3 additions & 1 deletion src/Nethermind/Nethermind.Db/IDbProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@

using System;
using System.Collections.Generic;
using Autofac;
using Microsoft.Extensions.DependencyInjection;
using Nethermind.Core;

namespace Nethermind.Db
{
Expand Down Expand Up @@ -32,7 +34,7 @@ public interface IDbProvider : IDisposable
void RegisterColumnDb<T>(string dbName, IColumnsDb<T> db);
IEnumerable<KeyValuePair<string, IDbMeta>> GetAllDbMeta();

void ConfigureServiceCollection(IServiceCollection sc)
void ConfigureServiceCollection(ContainerBuilder sc)
{
sc.AddSingleton(this);

Expand Down
7 changes: 3 additions & 4 deletions src/Nethermind/Nethermind.Init/Steps/InitializeNetwork.cs
Original file line number Diff line number Diff line change
Expand Up @@ -130,16 +130,15 @@ private async Task Initialize(CancellationToken cancellationToken)

if (_api.Synchronizer is null)
{
IServiceCollection serviceCollection = _api.CreateServiceCollectionFromApiWithNetwork(new ServiceCollection())
.AddSingleton<IBeaconSyncStrategy>(No.BeaconSync);

if (_api.ChainSpec.SealEngineType == SealEngineType.Clique)
_syncConfig.NeedToWaitForHeader = true; // Should this be in chainspec itself?

ContainerBuilder builder = new ContainerBuilder();
builder.Populate(serviceCollection);
_api.CreateServiceCollectionFromApiWithNetwork(builder)
.AddSingleton<IBeaconSyncStrategy>(No.BeaconSync);
Synchronizer.ConfigureContainerBuilder(builder, _syncConfig);
IContainer container = builder.Build();

_api.ApiWithNetworkServiceContainer = container;
_api.DisposeStack.Append(container);
}
Expand Down
8 changes: 4 additions & 4 deletions src/Nethermind/Nethermind.Merge.Plugin/MergePlugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -440,16 +440,16 @@ public Task InitSynchronization()

_api.Pivot = _beaconPivot;

IServiceCollection serviceCollection = _api.CreateServiceCollectionFromApiWithNetwork(new ServiceCollection())
ContainerBuilder builder = new ContainerBuilder();

_api.CreateServiceCollectionFromApiWithNetwork(builder)
.AddSingleton<IBeaconSyncStrategy>(_beaconSync)
.AddSingleton<IBeaconPivot>(_beaconPivot)
.AddSingleton(_mergeConfig)
.AddSingleton<IInvalidChainTracker>(_invalidChainTracker);

ContainerBuilder builder = new ContainerBuilder();
builder.Populate(serviceCollection);
Synchronizer.ConfigureContainerBuilder(builder, _syncConfig);
MergeSynchronizer.ConfigureMergeComponent(builder);

IContainer container = builder.Build();
_api.ApiWithNetworkServiceContainer = container;
_api.DisposeStack.Append(container);
Expand Down
7 changes: 3 additions & 4 deletions src/Nethermind/Nethermind.Optimism/OptimismPlugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -152,18 +152,17 @@ public Task InitSynchronization()
_api.BetterPeerStrategy = new MergeBetterPeerStrategy(null!, _api.PoSSwitcher, _beaconPivot, _api.LogManager);
_api.Pivot = _beaconPivot;

IServiceCollection serviceCollection = ((INethermindApi)_api).CreateServiceCollectionFromApiWithNetwork(new ServiceCollection())
ContainerBuilder builder = new ContainerBuilder();
((INethermindApi)_api).CreateServiceCollectionFromApiWithNetwork(builder)
.AddSingleton<IBeaconSyncStrategy>(_beaconSync)
.AddSingleton(_beaconPivot)
.AddSingleton(_api.PoSSwitcher)
.AddSingleton(_mergeConfig)
.AddSingleton(_invalidChainTracker);

ContainerBuilder builder = new ContainerBuilder();
builder.Populate(serviceCollection);
Synchronizer.ConfigureContainerBuilder(builder, _syncConfig);
MergeSynchronizer.ConfigureMergeComponent(builder);
IContainer container = builder.Build();

_api.ApiWithNetworkServiceContainer = container;
_api.DisposeStack.Append(container);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ public async Task Setup()

IStateReader stateReader = new StateReader(trieStore, _codeDb, LimboLogs.Instance);

IServiceCollection serviceCollection = new ServiceCollection()
ContainerBuilder builder = new ContainerBuilder()
.AddSingleton(nodeStorage)
.AddSingleton<ISpecProvider>(MainnetSpecProvider.Instance)
.AddSingleton(_blockTree)
Expand All @@ -86,11 +86,9 @@ public async Task Setup()
.AddSingleton(stateReader)
.AddSingleton<IBeaconSyncStrategy>(No.BeaconSync)
.AddSingleton<ILogManager>(LimboLogs.Instance);
dbProvider.ConfigureServiceCollection(serviceCollection);

ContainerBuilder builder = new ContainerBuilder();
builder.Populate(serviceCollection);
dbProvider.ConfigureServiceCollection(builder);
Synchronizer.ConfigureContainerBuilder(builder, syncConfig);

IContainer container = builder.Build();

_synchronizer = container.Resolve<Synchronizer>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,8 @@ private SyncTestContext CreateSyncManager(int index)
TotalDifficultyBetterPeerStrategy bestPeerStrategy = new(LimboLogs.Instance);
Pivot pivot = new(syncConfig);

IServiceCollection serviceCollection = new ServiceCollection()
ContainerBuilder builder = new ContainerBuilder();
builder
.AddSingleton(dbProvider)
.AddSingleton<INodeStorage>(new NodeStorage(dbProvider.StateDb))
.AddSingleton<ISpecProvider>(MainnetSpecProvider.Instance)
Expand All @@ -380,10 +381,7 @@ private SyncTestContext CreateSyncManager(int index)
.AddSingleton<IReceiptStorage>(receiptStorage)
.AddSingleton<IBeaconSyncStrategy>(No.BeaconSync)
.AddSingleton<ILogManager>(logManager);
dbProvider.ConfigureServiceCollection(serviceCollection);

ContainerBuilder builder = new ContainerBuilder();
builder.Populate(serviceCollection);
dbProvider.ConfigureServiceCollection(builder);
Synchronizer.ConfigureContainerBuilder(builder, syncConfig);
IContainer container = builder.Build();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -344,10 +344,10 @@ ISyncConfig GetSyncConfig() =>

IInvalidChainTracker invalidChainTracker = new NoopInvalidChainTracker();

IServiceCollection serviceCollection = new ServiceCollection();
dbProvider.ConfigureServiceCollection(serviceCollection);
ContainerBuilder builder = new ContainerBuilder();
dbProvider.ConfigureServiceCollection(builder);

serviceCollection
builder
.AddSingleton(dbProvider)
.AddSingleton(nodeStorage)
.AddSingleton<ISpecProvider>(MainnetSpecProvider.Instance)
Expand All @@ -370,8 +370,6 @@ ISyncConfig GetSyncConfig() =>
.AddSingleton(beaconPivot)
.AddSingleton(_logManager);

ContainerBuilder builder = new ContainerBuilder();
builder.Populate(serviceCollection);
Nethermind.Synchronization.Synchronizer.ConfigureContainerBuilder(builder, syncConfig);

if (IsMerge(synchronizerType))
Expand Down

0 comments on commit 1c54c1d

Please sign in to comment.