Skip to content

Commit 22d8700

Browse files
committed
fix: self review 1
1 parent 6d314aa commit 22d8700

File tree

6 files changed

+73
-44
lines changed

6 files changed

+73
-44
lines changed

src/Examples/JsonApiDotNetCoreExample/Startups/Startup.cs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,8 @@ public override void ConfigureServices(IServiceCollection services)
3939
options.UseNpgsql(_connectionString, innerOptions => innerOptions.SetPostgresVersion(new Version(9, 6)));
4040
}, ServiceLifetime.Transient);
4141

42-
services.AddJsonApi<AppDbContext>(ConfigureJsonApiOptions, discovery =>
43-
{
44-
discovery.AddCurrentAssembly();
45-
// discovery.AddAssembly(AppDomain.CurrentDomain
46-
// .GetAssemblies()
47-
// .First(a => a.FullName.Contains("JsonApiDotNetCoreExampleTests")));
48-
});
49-
42+
services.AddJsonApi<AppDbContext>(ConfigureJsonApiOptions, discovery => discovery.AddCurrentAssembly());
43+
5044
// once all tests have been moved to WebApplicationFactory format we can get rid of this line below
5145
services.AddClientSerialization();
5246
}

src/JsonApiDotNetCore/AssemblyInfo.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System.Runtime.CompilerServices;
22
[assembly:InternalsVisibleTo("UnitTests")]
3+
[assembly:InternalsVisibleTo("DiscoveryTests")]
34
[assembly:InternalsVisibleTo("JsonApiDotNetCoreExampleTests")]
45
[assembly:InternalsVisibleTo("NoEntityFrameworkTests")]
56
[assembly:InternalsVisibleTo("Benchmarks")]

src/JsonApiDotNetCore/Builders/JsonApiApplicationBuilder.cs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -74,22 +74,22 @@ public void ConfigureMvc()
7474
{
7575
RegisterJsonApiStartupServices();
7676

77-
using (var resourceConfigurationTemporaryProvider = _services.BuildServiceProvider())
77+
using (var resourceConfigurationIntermediateProvider = _services.BuildServiceProvider())
7878
{
79-
_resourceGraphBuilder = resourceConfigurationTemporaryProvider.GetRequiredService<IResourceGraphBuilder>();
80-
_serviceDiscoveryFacade = resourceConfigurationTemporaryProvider.GetRequiredService<IServiceDiscoveryFacade>();
81-
_services.AddSingleton(BuildResourceGraph(resourceConfigurationTemporaryProvider));
79+
_resourceGraphBuilder = resourceConfigurationIntermediateProvider.GetRequiredService<IResourceGraphBuilder>();
80+
_serviceDiscoveryFacade = resourceConfigurationIntermediateProvider.GetRequiredService<IServiceDiscoveryFacade>();
81+
_services.AddSingleton(BuildResourceGraph(resourceConfigurationIntermediateProvider));
8282
}
8383

8484
IJsonApiExceptionFilterProvider exceptionFilterProvider;
8585
IJsonApiTypeMatchFilterProvider typeMatchFilterProvider;
8686
IJsonApiRoutingConvention routingConvention;
8787

88-
using (var middlewareConfigurationTemporaryProvider = _services.BuildServiceProvider())
88+
using (var middlewareConfigurationIntermediateProvider = _services.BuildServiceProvider())
8989
{
90-
exceptionFilterProvider = middlewareConfigurationTemporaryProvider.GetRequiredService<IJsonApiExceptionFilterProvider>();
91-
typeMatchFilterProvider = middlewareConfigurationTemporaryProvider.GetRequiredService<IJsonApiTypeMatchFilterProvider>();
92-
routingConvention = middlewareConfigurationTemporaryProvider.GetRequiredService<IJsonApiRoutingConvention>();
90+
exceptionFilterProvider = middlewareConfigurationIntermediateProvider.GetRequiredService<IJsonApiExceptionFilterProvider>();
91+
typeMatchFilterProvider = middlewareConfigurationIntermediateProvider.GetRequiredService<IJsonApiTypeMatchFilterProvider>();
92+
routingConvention = middlewareConfigurationIntermediateProvider.GetRequiredService<IJsonApiRoutingConvention>();
9393
}
9494

9595
_mvcBuilder.AddMvcOptions(options =>
@@ -117,7 +117,7 @@ public void ConfigureMvc()
117117
public void ConfigureServices()
118118
{
119119

120-
((ServiceDiscoveryFacade)_serviceDiscoveryFacade).DiscoverServices();
120+
_serviceDiscoveryFacade.DiscoverServices();
121121

122122
if (_dbContextType != null)
123123
{
@@ -276,12 +276,12 @@ private void AddResourceTypesFromDbContext(ServiceProvider intermediateProvider)
276276
}
277277

278278
/// <summary>
279-
/// Executes auto-discovery of JADNC services.
279+
/// Performs auto-discovery of JsonApiDotNetCore services.
280280
/// </summary>
281281
private void AutoDiscoverResources()
282282
{
283283
_configureAutoDiscovery?.Invoke(_serviceDiscoveryFacade);
284-
((ServiceDiscoveryFacade)_serviceDiscoveryFacade).DiscoverResources();
284+
_serviceDiscoveryFacade.DiscoverResources();
285285
}
286286

287287
/// <summary>

src/JsonApiDotNetCore/Graph/IServiceDiscoveryFacade.cs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,23 @@ namespace JsonApiDotNetCore.Graph
44
{
55
public interface IServiceDiscoveryFacade
66
{
7+
/// <summary>
8+
/// Registers the designated assembly for discovery of JsonApiDotNetCore services and resources.
9+
/// </summary>
710
ServiceDiscoveryFacade AddAssembly(Assembly assembly);
11+
/// <summary>
12+
/// Registers the current assembly for discovery of JsonApiDotNetCore services and resources.
13+
/// </summary>
814
ServiceDiscoveryFacade AddCurrentAssembly();
15+
16+
/// <summary>
17+
/// Discovers JsonApiDotNetCore services in the registered assemblies and adds them to the DI container.
18+
/// </summary>
19+
internal void DiscoverServices();
20+
21+
/// <summary>
22+
/// Discovers JsonApiDotNetCore resources in the registered assemblies and adds them to the resource graph.
23+
/// </summary>
24+
internal void DiscoverResources();
925
}
10-
}
26+
}

src/JsonApiDotNetCore/Graph/ServiceDiscoveryFacade.cs

Lines changed: 37 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public class ServiceDiscoveryFacade : IServiceDiscoveryFacade
3737
typeof(IDeleteService<,>)
3838
};
3939

40-
private static readonly HashSet<Type> RepositoryInterfaces = new HashSet<Type> {
40+
private static readonly HashSet<Type> _repositoryInterfaces = new HashSet<Type> {
4141
typeof(IResourceRepository<>),
4242
typeof(IResourceRepository<,>),
4343
typeof(IResourceWriteRepository<>),
@@ -50,44 +50,48 @@ public class ServiceDiscoveryFacade : IServiceDiscoveryFacade
5050
private readonly IResourceGraphBuilder _resourceGraphBuilder;
5151
private readonly IdentifiableTypeCache _typeCache = new IdentifiableTypeCache();
5252
private readonly Dictionary<Assembly, IEnumerable<ResourceDescriptor>> _discoverableAssemblies = new Dictionary<Assembly, IEnumerable<ResourceDescriptor>>();
53+
5354
public ServiceDiscoveryFacade(IServiceCollection services, IResourceGraphBuilder resourceGraphBuilder)
5455
{
5556
_services = services;
5657
_resourceGraphBuilder = resourceGraphBuilder;
5758
}
5859

59-
/// <summary>
60-
/// Adds resource, service and repository implementations to the container.
61-
/// </summary>
60+
/// <inheritdoc/>
6261
public ServiceDiscoveryFacade AddCurrentAssembly() => AddAssembly(Assembly.GetCallingAssembly());
6362

64-
/// <summary>
65-
/// Adds resource, service and repository implementations defined in the specified assembly to the container.
66-
/// </summary>
63+
/// <inheritdoc/>
6764
public ServiceDiscoveryFacade AddAssembly(Assembly assembly)
6865
{
69-
_discoverableAssemblies.Add(assembly, _typeCache.GetIdentifiableTypes(assembly));
66+
_discoverableAssemblies.Add(assembly, null);
7067

7168
return this;
7269
}
7370

74-
public void DiscoverResources()
71+
/// <inheritdoc/>
72+
void IServiceDiscoveryFacade.DiscoverResources()
7573
{
76-
foreach (var (assembly, resourceDescriptors) in _discoverableAssemblies)
74+
75+
foreach (var (assembly, discoveredResourceDescriptors) in _discoverableAssemblies)
7776
{
77+
var resourceDescriptors = GetOrSetResourceDescriptors(discoveredResourceDescriptors, assembly);
78+
7879
foreach (var descriptor in resourceDescriptors)
7980
{
8081
AddResource(assembly, descriptor);
8182
}
8283
}
8384
}
84-
85-
public void DiscoverServices()
85+
86+
/// <inheritdoc/>
87+
void IServiceDiscoveryFacade.DiscoverServices()
8688
{
87-
foreach (var (assembly, resourceDescriptors) in _discoverableAssemblies)
89+
foreach (var (assembly, discoveredResourceDescriptors) in _discoverableAssemblies)
8890
{
8991
AddDbContextResolvers(assembly);
9092

93+
var resourceDescriptors = GetOrSetResourceDescriptors(discoveredResourceDescriptors, assembly);
94+
9195
foreach (var descriptor in resourceDescriptors)
9296
{
9397
AddResourceDefinition(assembly, descriptor);
@@ -106,8 +110,6 @@ private void AddDbContextResolvers(Assembly assembly)
106110
_services.AddScoped(typeof(IDbContextResolver), resolverType);
107111
}
108112
}
109-
110-
111113

112114
private void AddResource(Assembly assembly, ResourceDescriptor resourceDescriptor)
113115
{
@@ -140,7 +142,7 @@ private void AddServices(Assembly assembly, ResourceDescriptor resourceDescripto
140142

141143
private void AddRepositories(Assembly assembly, ResourceDescriptor resourceDescriptor)
142144
{
143-
foreach (var serviceInterface in RepositoryInterfaces)
145+
foreach (var serviceInterface in _repositoryInterfaces)
144146
{
145147
RegisterServiceImplementations(assembly, serviceInterface, resourceDescriptor);
146148
}
@@ -153,12 +155,28 @@ private void RegisterServiceImplementations(Assembly assembly, Type interfaceTyp
153155
return;
154156
}
155157
var genericArguments = interfaceType.GetTypeInfo().GenericTypeParameters.Length == 2 ? new[] { resourceDescriptor.ResourceType, resourceDescriptor.IdType } : new[] { resourceDescriptor.ResourceType };
156-
var service = TypeLocator.GetGenericInterfaceImplementation(assembly, interfaceType, genericArguments);
158+
var (implementation, registrationInterface) = TypeLocator.GetGenericInterfaceImplementation(assembly, interfaceType, genericArguments);
157159

158-
if (service.implementation != null)
160+
if (implementation != null)
159161
{
160-
_services.AddScoped(service.registrationInterface, service.implementation);
162+
_services.AddScoped(registrationInterface, implementation);
161163
}
162164
}
165+
166+
private IEnumerable<ResourceDescriptor> GetOrSetResourceDescriptors(IEnumerable<ResourceDescriptor> discoveredResourceDescriptors, Assembly assembly)
167+
{
168+
IEnumerable<ResourceDescriptor> resourceDescriptors;
169+
if (discoveredResourceDescriptors == null)
170+
{
171+
resourceDescriptors = _typeCache.GetIdentifiableTypes(assembly);
172+
_discoverableAssemblies[assembly] = resourceDescriptors;
173+
}
174+
else
175+
{
176+
resourceDescriptors = discoveredResourceDescriptors;
177+
}
178+
179+
return resourceDescriptors;
180+
}
163181
}
164182
}

test/DiscoveryTests/ServiceDiscoveryFacadeTests.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,10 @@ public ServiceDiscoveryFacadeTests()
5959
public void AddAssembly_Adds_All_Resources_To_Graph()
6060
{
6161
// Arrange, act
62-
var facade = new ServiceDiscoveryFacade(_services, _resourceGraphBuilder);
62+
IServiceDiscoveryFacade facade = new ServiceDiscoveryFacade(_services, _resourceGraphBuilder);
6363
facade.AddAssembly(typeof(Person).Assembly);
6464
facade.DiscoverResources();
65-
65+
6666
// Assert
6767
var resourceGraph = _resourceGraphBuilder.Build();
6868
var personResource = resourceGraph.GetResourceContext(typeof(Person));
@@ -76,7 +76,7 @@ public void AddAssembly_Adds_All_Resources_To_Graph()
7676
public void AddCurrentAssembly_Adds_Resources_To_Graph()
7777
{
7878
// Arrange, act
79-
var facade = new ServiceDiscoveryFacade(_services, _resourceGraphBuilder);
79+
IServiceDiscoveryFacade facade = new ServiceDiscoveryFacade(_services, _resourceGraphBuilder);
8080
facade.AddCurrentAssembly();
8181
facade.DiscoverResources();
8282

@@ -90,7 +90,7 @@ public void AddCurrentAssembly_Adds_Resources_To_Graph()
9090
public void AddCurrentAssembly_Adds_Services_To_Container()
9191
{
9292
// Arrange, act
93-
var facade = new ServiceDiscoveryFacade(_services, _resourceGraphBuilder);
93+
IServiceDiscoveryFacade facade = new ServiceDiscoveryFacade(_services, _resourceGraphBuilder);
9494
facade.AddCurrentAssembly();
9595
facade.DiscoverServices();
9696

@@ -104,7 +104,7 @@ public void AddCurrentAssembly_Adds_Services_To_Container()
104104
public void AddCurrentAssembly_Adds_Repositories_To_Container()
105105
{
106106
// Arrange, act
107-
var facade = new ServiceDiscoveryFacade(_services, _resourceGraphBuilder);
107+
IServiceDiscoveryFacade facade = new ServiceDiscoveryFacade(_services, _resourceGraphBuilder);
108108
facade.AddCurrentAssembly();
109109
facade.DiscoverServices();
110110

0 commit comments

Comments
 (0)