Skip to content

Commit d6f763f

Browse files
committed
chore: final stretch
1 parent 2843111 commit d6f763f

File tree

8 files changed

+106
-17
lines changed

8 files changed

+106
-17
lines changed

src/Examples/JsonApiDotNetCoreExample/Startup.cs

+4-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public Startup(IWebHostEnvironment env)
2525
}
2626

2727
public virtual void ConfigureServices(IServiceCollection services)
28-
{
28+
{ services.AddJsonApi();
2929
var loggerFactory = new LoggerFactory();
3030
services
3131
.AddSingleton<ILoggerFactory>(loggerFactory)
@@ -44,6 +44,8 @@ public virtual void ConfigureServices(IServiceCollection services)
4444
options.LoaDatabaseValues = true;
4545
},
4646
discovery => discovery.AddCurrentAssembly());
47+
48+
4749
services.AddClientSerialization();
4850
}
4951

@@ -54,6 +56,7 @@ public virtual void Configure(
5456
{
5557

5658
context.Database.EnsureCreated();
59+
5760
app.UseJsonApi();
5861
}
5962

src/JsonApiDotNetCore/Builders/ResourceGraphBuilder.cs

+1-4
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,8 @@ public IResourceGraphBuilder AddResource<TResource, TId>(string pluralizedTypeNa
5959
public IResourceGraphBuilder AddResource(Type entityType, Type idType, string pluralizedTypeName = null)
6060
{
6161
AssertEntityIsNotAlreadyDefined(entityType);
62-
63-
pluralizedTypeName = pluralizedTypeName ?? _resourceNameFormatter.FormatResourceName(entityType);
64-
62+
pluralizedTypeName ??= _resourceNameFormatter.FormatResourceName(entityType);
6563
_entities.Add(GetEntity(pluralizedTypeName, entityType, idType));
66-
6764
return this;
6865
}
6966

src/JsonApiDotNetCore/Extensions/IServiceCollectionExtensions.cs

+6-4
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,10 @@ public static IServiceCollection AddJsonApi<TEfCoreDbContext>(this IServiceColle
3636
if (options != null)
3737
application.ConfigureJsonApiOptions(options);
3838
application.ConfigureLogging();
39-
application.ConfigureMvc();
4039
application.ConfigureResources<TEfCoreDbContext>(resources);
4140
application.ConfigureServices();
41+
application.ConfigureMvc();
42+
4243
return services;
4344
}
4445

@@ -58,12 +59,13 @@ public static IServiceCollection AddJsonApi(this IServiceCollection services,
5859
var application = new JsonApiApplicationBuilder(services, mvcBuilder ?? services.AddMvcCore());
5960
if (options != null)
6061
application.ConfigureJsonApiOptions(options);
61-
application.ConfigureMvc();
62-
if (discovery != null)
63-
application.AutoDiscover(discovery);
6462
if (resources != null)
6563
application.ConfigureResources(resources);
6664
application.ConfigureServices();
65+
application.ConfigureMvc();
66+
if (discovery != null)
67+
application.AutoDiscover(discovery);
68+
6769
return services;
6870
}
6971

src/JsonApiDotNetCore/Internal/DefaultRoutingConvention.cs

+31-3
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using JsonApiDotNetCore.Controllers;
77
using JsonApiDotNetCore.Extensions;
88
using JsonApiDotNetCore.Graph;
9+
using JsonApiDotNetCore.Internal.Contracts;
910
using JsonApiDotNetCore.Models;
1011
using Microsoft.AspNetCore.Mvc;
1112
using Microsoft.AspNetCore.Mvc.ApplicationModels;
@@ -37,12 +38,14 @@ public class DefaultRoutingConvention : IJsonApiRoutingConvention, IControllerRe
3738
{
3839
private readonly string _namespace;
3940
private readonly IResourceNameFormatter _formatter;
41+
private readonly IResourceGraph _resourceGraph;
4042
private readonly HashSet<string> _registeredTemplates = new HashSet<string>();
4143
private readonly Dictionary<string, Type> _registeredResources = new Dictionary<string, Type>();
42-
public DefaultRoutingConvention(IJsonApiOptions options, IResourceNameFormatter formatter)
44+
public DefaultRoutingConvention(IJsonApiOptions options, IResourceNameFormatter formatter, IResourceGraph resourceGraph)
4345
{
4446
_namespace = options.Namespace;
4547
_formatter = formatter;
48+
_resourceGraph = resourceGraph;
4649
}
4750

4851
/// <inheritdoc/>
@@ -58,18 +61,43 @@ public void Apply(ApplicationModel application)
5861
foreach (var controller in application.Controllers)
5962
{
6063
var resourceType = GetResourceTypeFromController(controller.ControllerType);
64+
6165
if (resourceType != null)
66+
{
6267
_registeredResources.Add(controller.ControllerName, resourceType);
68+
}
6369

6470
if (RoutingConventionDisabled(controller) == false)
71+
{
6572
continue;
73+
}
74+
// if defined in resourcegraph, it should be used
75+
var contexts = _resourceGraph.GetResourceContexts();
76+
77+
var foundResourceGraph = contexts.First(c => c.ResourceType == resourceType);
78+
string template = null;
79+
if (foundResourceGraph != null)
80+
{
81+
template = $"{_namespace}/{foundResourceGraph.ResourceName}";
82+
}
83+
else
84+
{
85+
template = TemplateFromResource(controller) ?? TemplateFromController(controller);
86+
}
6687

67-
var template = TemplateFromResource(controller) ?? TemplateFromController(controller);
6888
if (template == null)
89+
{
6990
throw new JsonApiSetupException($"Controllers with overlapping route templates detected: {controller.ControllerType.FullName}");
91+
}
7092

7193
controller.Selectors[0].AttributeRouteModel = new AttributeRouteModel { Template = template };
7294
}
95+
96+
}
97+
98+
public void HandleControllers(IList<ControllerModel> controllers)
99+
{
100+
73101
}
74102

75103
/// <summary>
@@ -128,7 +156,7 @@ private Type GetResourceTypeFromController(Type type)
128156
{
129157
var nextBaseType = currentBaseType.BaseType;
130158

131-
if ( (nextBaseType == controllerBase || nextBaseType == jsonApiMixin) && currentBaseType.IsGenericType)
159+
if ((nextBaseType == controllerBase || nextBaseType == jsonApiMixin) && currentBaseType.IsGenericType)
132160
{
133161
var potentialResource = currentBaseType.GetGenericArguments().FirstOrDefault(t => t.Inherits(identifiable));
134162
if (potentialResource != null)

test/NoEntityFrameworkTests/Acceptance/Extensibility/NoEntityFrameworkTests.cs

+1-2
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,7 @@ public async Task Can_Create_TodoItems()
9696
request.Content = new StringContent(JsonConvert.SerializeObject(content));
9797
request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/vnd.api+json");
9898

99-
var builder = new WebHostBuilder()
100-
.UseStartup<Startup>();
99+
var builder = new WebHostBuilder().UseStartup<Startup>();
101100
var server = new TestServer(builder);
102101
var client = server.CreateClient();
103102

test/NoEntityFrameworkTests/TestFixture.cs

+17-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using JsonApiDotNetCore.Builders;
2+
using JsonApiDotNetCore.Internal.Contracts;
23
using JsonApiDotNetCore.Models;
34
using JsonApiDotNetCore.Serialization.Client;
45
using JsonApiDotNetCoreExample;
@@ -23,6 +24,7 @@ public TestFixture()
2324
var builder = new WebHostBuilder().UseStartup<Startup>();
2425
Server = new TestServer(builder);
2526
Context = Server.GetService<AppDbContext>();
27+
2628
Context.Database.EnsureCreated();
2729
_services = Server.Host.Services;
2830
}
@@ -38,7 +40,13 @@ public IRequestSerializer GetSerializer<TResource>(Expression<Func<TResource, dy
3840
}
3941
public IResponseDeserializer GetDeserializer()
4042
{
41-
var resourceGraph = new ResourceGraphBuilder()
43+
IResourceGraph resourceGraph = GetResourceGraph();
44+
return new ResponseDeserializer(resourceGraph);
45+
}
46+
47+
private static IResourceGraph GetResourceGraph()
48+
{
49+
return new ResourceGraphBuilder()
4250
.AddResource<PersonRole>()
4351
.AddResource<Article>()
4452
.AddResource<Tag>()
@@ -49,10 +57,16 @@ public IResponseDeserializer GetDeserializer()
4957
.AddResource<Passport>()
5058
.AddResource<TodoItemClient>("custom-todo-items")
5159
.AddResource<TodoItemCollectionClient, Guid>().Build();
52-
return new ResponseDeserializer(resourceGraph);
5360
}
5461

55-
public T GetService<T>() => (T)_services.GetService(typeof(T));
62+
public T GetService<T>()
63+
{
64+
if(typeof(T) == typeof(IResourceGraph))
65+
{
66+
return (T) GetResourceGraph();
67+
}
68+
return (T)_services.GetService(typeof(T));
69+
}
5670

5771
public void Dispose()
5872
{
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
using JsonApiDotNetCore.Builders;
2+
using JsonApiDotNetCore.Configuration;
3+
using JsonApiDotNetCore.Graph;
4+
using JsonApiDotNetCore.Internal;
5+
using JsonApiDotNetCoreExample.Models;
6+
using Moq;
7+
using System;
8+
using System.Collections.Generic;
9+
using System.Text;
10+
using System.Threading.Tasks;
11+
using Microsoft.AspNetCore.Mvc.ApplicationModels;
12+
using JsonApiDotNetCoreExample.Controllers;
13+
using System.Reflection;
14+
using Xunit;
15+
using System.Linq;
16+
17+
namespace UnitTests.Routing
18+
{
19+
public class DefaultRoutingConventionTests
20+
{
21+
22+
[Fact]
23+
public void DefaultRoutingCustomRoute_CustomRouteRegistered_ShouldBeRegisteredAsTemplate()
24+
{
25+
// Arrange
26+
var mockOptions = new Mock<IJsonApiOptions>();
27+
var mockFormatter = new Mock<IResourceNameFormatter>();
28+
var resourceGraph = new ResourceGraphBuilder().AddResource<TodoItem>("customRouteForMe").Build();
29+
var convention = new DefaultRoutingConvention(mockOptions.Object, mockFormatter.Object, resourceGraph);
30+
var attributes = new List<object>().AsReadOnly();
31+
var controllerModel = new ControllerModel(typeof(TodoItemsController).GetTypeInfo(), attributes);
32+
controllerModel.ControllerName = "Test";
33+
var sModel = new SelectorModel();
34+
controllerModel.Selectors.Add(sModel);
35+
var appModel = new ApplicationModel();
36+
appModel.Controllers.Add(controllerModel);
37+
38+
// Act
39+
convention.Apply(appModel);
40+
41+
// Assert
42+
Assert.Equal("/customRouteForMe", controllerModel.Selectors[0].AttributeRouteModel.Template);
43+
}
44+
}
45+
}

test/UnitTests/UnitTests.csproj

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
<ItemGroup>
1111
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="3.0.0" />
1212
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.3.0" />
13+
<PackageReference Include="MSTest.TestFramework" Version="2.0.0" />
1314
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
1415
<PackageReference Include="xunit.runner.visualstudio" Version="$(XUnitVersion)" />
1516
<PackageReference Include="xunit" Version="$(XUnitVersion)" />

0 commit comments

Comments
 (0)