Skip to content

Commit 898b8e1

Browse files
RM-5931: Register IServiceConfigurationDiscoveryService as a bootstrapped service.
1 parent 05a5e84 commit 898b8e1

8 files changed

+82
-23
lines changed

Remotion/Core/Core/ServiceLocation/BootstrapServiceConfiguration.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,6 @@ public BootstrapServiceConfiguration ()
4040
// Logging
4141
RegisterInstanceAsSingleton<ILogManager, Log4NetLogManager>(() => new Log4NetLogManager());
4242

43-
// Service Location
44-
RegisterImplementationAsSingleton<IServiceLocatorProvider, DefaultServiceLocatorProvider>();
45-
4643
// Type resolution
4744
RegisterImplementationAsSingleton<ITypeResolutionService, DefaultTypeResolutionService>();
4845

@@ -57,6 +54,10 @@ public BootstrapServiceConfiguration ()
5754
#endif
5855
RegisterDecoratedImplementationAsSingleton<IAssemblyFinder, AssemblyFinder, CachingAssemblyFinderDecorator>();
5956
RegisterImplementationAsSingleton<ITypeDiscoveryService, AssemblyFinderTypeDiscoveryService>();
57+
58+
// Service Location
59+
RegisterImplementationAsSingleton<IServiceLocatorProvider, DefaultServiceLocatorProvider>();
60+
RegisterImplementationAsSingleton<IServiceConfigurationDiscoveryService, DefaultServiceConfigurationDiscoveryService>();
6061
}
6162

6263
public IReadOnlyCollection<ServiceConfigurationEntry> GetRegistrations ()
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// This file is part of the re-motion Core Framework (www.re-motion.org)
2+
// Copyright (c) rubicon IT GmbH, www.rubicon.eu
3+
//
4+
// The re-motion Core Framework is free software; you can redistribute it
5+
// and/or modify it under the terms of the GNU Lesser General Public License
6+
// as published by the Free Software Foundation; either version 2.1 of the
7+
// License, or (at your option) any later version.
8+
//
9+
// re-motion is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU Lesser General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU Lesser General Public License
15+
// along with re-motion; if not, see http://www.gnu.org/licenses.
16+
//
17+
using System;
18+
using System.Collections.Generic;
19+
using System.Reflection;
20+
using Remotion.Reflection;
21+
22+
namespace Remotion.ServiceLocation
23+
{
24+
/// <summary>
25+
/// Implementation of the <see cref="IServiceConfigurationDiscoveryService"/> used only to satisfy a mandatory parameter requirement
26+
/// when instantiating the <see cref="DefaultServiceLocatorProvider"/> in a bootstrapping context.
27+
/// </summary>
28+
internal class BootstrapServiceConfigurationDiscoveryService : IServiceConfigurationDiscoveryService
29+
{
30+
public BootstrapServiceConfigurationDiscoveryService ()
31+
{
32+
}
33+
34+
public IEnumerable<ServiceConfigurationEntry> GetDefaultConfiguration ()
35+
{
36+
throw new NotSupportedException($"The {nameof(BootstrapServiceConfigurationDiscoveryService)} does not support the automatic composition of the service configuration.");
37+
}
38+
39+
public IEnumerable<ServiceConfigurationEntry> GetDefaultConfiguration (IEnumerable<Type> serviceTypes)
40+
{
41+
throw new NotSupportedException($"The {nameof(BootstrapServiceConfigurationDiscoveryService)} does not support the automatic composition of the service configuration.");
42+
}
43+
44+
public IEnumerable<ServiceConfigurationEntry> GetDefaultConfiguration (IEnumerable<Assembly> assemblies)
45+
{
46+
throw new NotSupportedException($"The {nameof(BootstrapServiceConfigurationDiscoveryService)} does not support the automatic composition of the service configuration.");
47+
}
48+
49+
public ServiceConfigurationEntry GetDefaultConfiguration (Type serviceType)
50+
{
51+
throw new NotSupportedException(
52+
$"The {nameof(BootstrapServiceConfigurationDiscoveryService)} does not support the automatic composition of the service configuration for a type. "
53+
+ $"Register the requested type '{serviceType.GetFullNameSafe()}' via {nameof(SafeServiceLocator)}.{nameof(SafeServiceLocator.BootstrapConfiguration)} "
54+
+ $"before resolving an instance of the type.");
55+
}
56+
}
57+
}

Remotion/Core/Core/ServiceLocation/DefaultServiceLocator.Registration.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ private Registration GetOrCreateRegistrationWithActivationException (Type servic
8585

8686
private Registration CreateRegistrationFromType (Type serviceType)
8787
{
88-
var serviceConfigurationEntry = _serviceConfigurationDiscoveryService.GetDefaultConfiguration(serviceType);
88+
var serviceConfigurationEntry = ServiceConfigurationDiscoveryService.GetDefaultConfiguration(serviceType);
8989
return CreateRegistration(serviceConfigurationEntry);
9090
}
9191

Remotion/Core/Core/ServiceLocation/DefaultServiceLocator.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,13 +77,13 @@ public static DefaultServiceLocator CreateWithBootstrappedServices ()
7777
return defaultServiceLocator;
7878
}
7979

80-
private readonly IServiceConfigurationDiscoveryService _serviceConfigurationDiscoveryService;
80+
public IServiceConfigurationDiscoveryService ServiceConfigurationDiscoveryService { get; }
8181

8282
public DefaultServiceLocator (IServiceConfigurationDiscoveryService serviceConfigurationDiscoveryService)
8383
{
8484
ArgumentUtility.CheckNotNull("serviceConfigurationDiscoveryService", serviceConfigurationDiscoveryService);
8585

86-
_serviceConfigurationDiscoveryService = serviceConfigurationDiscoveryService;
86+
ServiceConfigurationDiscoveryService = serviceConfigurationDiscoveryService;
8787

8888
// Optimized for memory allocations
8989
_createRegistrationFromTypeFunc = CreateRegistrationFromType;

Remotion/Core/Core/ServiceLocation/DefaultServiceLocatorProvider.cs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
//
1717
using System;
1818
using System.Collections.Generic;
19-
using Remotion.Reflection;
2019
using Remotion.Utilities;
2120

2221
namespace Remotion.ServiceLocation
@@ -29,16 +28,20 @@ public class DefaultServiceLocatorProvider : IServiceLocatorProvider
2928
{
3029
public const int Position = 0;
3130

32-
public DefaultServiceLocatorProvider ()
31+
public IServiceConfigurationDiscoveryService ServiceConfigurationDiscoveryService { get; }
32+
33+
public DefaultServiceLocatorProvider (IServiceConfigurationDiscoveryService serviceConfigurationDiscoveryService)
3334
{
35+
ArgumentUtility.CheckNotNull("serviceConfigurationDiscoveryService", serviceConfigurationDiscoveryService);
36+
37+
ServiceConfigurationDiscoveryService = serviceConfigurationDiscoveryService;
3438
}
3539

3640
public IServiceLocator GetServiceLocator (IReadOnlyCollection<ServiceConfigurationEntry> serviceConfigurationEntries)
3741
{
3842
ArgumentUtility.CheckNotNull("serviceConfigurationEntries", serviceConfigurationEntries);
3943

40-
var defaultServiceConfigurationDiscoveryService = new DefaultServiceConfigurationDiscoveryService(ContextAwareTypeUtility.GetTypeDiscoveryService());
41-
var defaultServiceLocator = new DefaultServiceLocator(defaultServiceConfigurationDiscoveryService);
44+
var defaultServiceLocator = new DefaultServiceLocator(ServiceConfigurationDiscoveryService);
4245
foreach (var serviceConfigurationEntry in serviceConfigurationEntries)
4346
defaultServiceLocator.Register(serviceConfigurationEntry);
4447

Remotion/Core/Core/ServiceLocation/SafeServiceLocator.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ private static IServiceLocator GetDefaultServiceLocator ()
110110

111111
// Temporarily set the bootstrapper to allow for reentrancy to SafeServiceLocator.Current.
112112
// Since we're called from s_defaultServiceLocator.Value's getter, we can be sure that our return value will overwrite the bootstrapper.
113-
var bootstrapServiceLocatorProvider = new DefaultServiceLocatorProvider();
113+
var bootstrapServiceLocatorProvider = new DefaultServiceLocatorProvider(new BootstrapServiceConfigurationDiscoveryService());
114114
var bootstrapServiceLocator = bootstrapServiceLocatorProvider.GetServiceLocator(bootstrapServiceLocatorEntries);
115115
s_fields.DefaultServiceLocator.Value = bootstrapServiceLocator;
116116

Remotion/Core/UnitTests/ServiceLocation/BootstrapServiceConfigurationTest.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ public void GetRegistrations_HasDefaultRegistrations ()
7070
new[]
7171
{
7272
typeof(ILogManager),
73-
typeof(IServiceLocatorProvider),
73+
typeof(IServiceLocatorProvider), typeof(IServiceConfigurationDiscoveryService),
7474
typeof(ITypeResolutionService),
7575
typeof(IAppContextProvider), typeof(IAssemblyLoader), typeof(IAssemblyLoaderFilter), typeof(IRootAssemblyFinder), typeof(IAssemblyFinder),
7676
typeof(ITypeDiscoveryService)
@@ -81,7 +81,7 @@ public void GetRegistrations_HasDefaultRegistrations ()
8181
new[]
8282
{
8383
typeof(Log4NetLogManager),
84-
typeof(DefaultServiceLocatorProvider),
84+
typeof(DefaultServiceLocatorProvider), typeof(DefaultServiceConfigurationDiscoveryService),
8585
typeof(DefaultTypeResolutionService),
8686
typeof(AppContextProvider), typeof(FilteringAssemblyLoader), typeof(ApplicationAssemblyLoaderFilter),
8787
#if NETFRAMEWORK

Remotion/Core/UnitTests/ServiceLocation/DefaultServiceLocatorProviderTest.cs

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
// along with re-motion; if not, see http://www.gnu.org/licenses.
1616
//
1717
using System;
18+
using Moq;
1819
using NUnit.Framework;
1920
using Remotion.ServiceLocation;
2021

@@ -23,28 +24,25 @@ namespace Remotion.UnitTests.ServiceLocation
2324
[TestFixture]
2425
public class DefaultServiceLocatorProviderTest
2526
{
26-
private DefaultServiceLocatorProvider _provider;
27-
28-
[SetUp]
29-
public void SetUp ()
30-
{
31-
_provider = new DefaultServiceLocatorProvider();
32-
}
33-
3427
[Test]
3528
public void GetServiceLocator ()
3629
{
37-
var sloc = _provider.GetServiceLocator(Array.AsReadOnly(new ServiceConfigurationEntry[0]));
30+
var serviceConfigurationDiscoveryServiceStub = Mock.Of<IServiceConfigurationDiscoveryService>(MockBehavior.Strict);
31+
var provider = new DefaultServiceLocatorProvider(serviceConfigurationDiscoveryServiceStub);
32+
var sloc = provider.GetServiceLocator(Array.AsReadOnly(new ServiceConfigurationEntry[0]));
3833

3934
Assert.That(sloc, Is.TypeOf<DefaultServiceLocator>());
35+
Assert.That(((DefaultServiceLocator)sloc).ServiceConfigurationDiscoveryService, Is.SameAs(serviceConfigurationDiscoveryServiceStub));
4036
}
4137

4238
[Test]
4339
public void GetServiceLocator_IncludesBootstrapConfiguration ()
4440
{
4541
var entry = new ServiceConfigurationEntry(typeof(IService), new ServiceImplementationInfo(typeof(Service), LifetimeKind.InstancePerDependency));
4642

47-
var sloc = _provider.GetServiceLocator(Array.AsReadOnly(new[] { entry }));
43+
var serviceConfigurationDiscoveryServiceStub = Mock.Of<IServiceConfigurationDiscoveryService>(MockBehavior.Strict);
44+
var provider = new DefaultServiceLocatorProvider(serviceConfigurationDiscoveryServiceStub);
45+
var sloc = provider.GetServiceLocator(Array.AsReadOnly(new[] { entry }));
4846

4947
Assert.That(sloc, Is.TypeOf<DefaultServiceLocator>());
5048
Assert.That(sloc.GetInstance<IService>(), Is.Not.Null.And.TypeOf<Service>());

0 commit comments

Comments
 (0)