Skip to content
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ See [the documentation](https://json-api-dotnet.github.io/#/) for detailed usage

```csharp
public class Article : Identifiable
{
{
[Attr("name")]
public string Name { get; set; }
}
Expand Down Expand Up @@ -91,7 +91,7 @@ Running tests locally requires access to a postgresql database.
If you have docker installed, this can be propped up via:

```bash
docker run --rm --name jsonapi-dotnet-core-testing -e POSTGRES_DB=JsonApiDotNetCoreExample -e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=postgres -p 5432:5432 postgres
docker run --rm --name jsonapi-dotnet-core-testing -e POSTGRES_DB=JsonApiDotNetCoreExample -e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=postgres -p 5432:5432 postgres
```

And then to run the tests:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Attributes.Exporters;
using BenchmarkDotNet.Attributes.Jobs;
using System;

namespace Benchmarks.LinkBuilder
{
[MarkdownExporter, SimpleJob(launchCount : 3, warmupCount : 10, targetCount : 20), MemoryDiagnoser]
[MarkdownExporter, SimpleJob(launchCount: 3, warmupCount: 10, targetCount: 20), MemoryDiagnoser]
public class LinkBuilder_GetNamespaceFromPath_Benchmarks
{
private const string PATH = "/api/some-really-long-namespace-path/resources/current/articles";
Expand All @@ -14,7 +15,7 @@ public class LinkBuilder_GetNamespaceFromPath_Benchmarks
public void UsingSplit() => GetNamespaceFromPath_BySplitting(PATH, ENTITY_NAME);

[Benchmark]
public void Current() => GetNameSpaceFromPath_Current(PATH, ENTITY_NAME);
public void Current() => GetNameSpaceFromPathCurrent(PATH, ENTITY_NAME);

public static string GetNamespaceFromPath_BySplitting(string path, string entityName)
{
Expand All @@ -32,7 +33,38 @@ public static string GetNamespaceFromPath_BySplitting(string path, string entity
return nSpace;
}

public static string GetNameSpaceFromPath_Current(string path, string entityName)
=> JsonApiDotNetCore.Builders.LinkBuilder.GetNamespaceFromPath(path, entityName);
public static string GetNameSpaceFromPathCurrent(string path, string entityName)
{

var entityNameSpan = entityName.AsSpan();
var pathSpan = path.AsSpan();
const char delimiter = '/';
for (var i = 0; i < pathSpan.Length; i++)
{
if (pathSpan[i].Equals(delimiter))
{
var nextPosition = i + 1;
if (pathSpan.Length > i + entityNameSpan.Length)
{
var possiblePathSegment = pathSpan.Slice(nextPosition, entityNameSpan.Length);
if (entityNameSpan.SequenceEqual(possiblePathSegment))
{
// check to see if it's the last position in the string
// or if the next character is a /
var lastCharacterPosition = nextPosition + entityNameSpan.Length;

if (lastCharacterPosition == pathSpan.Length || pathSpan.Length >= lastCharacterPosition + 2 && pathSpan[lastCharacterPosition].Equals(delimiter))
{
return pathSpan.Slice(0, i).ToString();
}
}
}
}
}

return string.Empty;


}
}
}
4 changes: 2 additions & 2 deletions benchmarks/Program.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using BenchmarkDotNet.Running;
using BenchmarkDotNet.Running;
using Benchmarks.JsonApiContext;
using Benchmarks.LinkBuilder;
using Benchmarks.Query;
Expand All @@ -10,7 +10,7 @@ class Program {
static void Main(string[] args) {
var switcher = new BenchmarkSwitcher(new[] {
typeof(JsonApiDeserializer_Benchmarks),
typeof(JsonApiSerializer_Benchmarks),
//typeof(JsonApiSerializer_Benchmarks),
typeof(QueryParser_Benchmarks),
typeof(LinkBuilder_GetNamespaceFromPath_Benchmarks),
typeof(ContainsMediaTypeParameters_Benchmarks),
Expand Down
11 changes: 6 additions & 5 deletions benchmarks/Query/QueryParser_Benchmarks.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using BenchmarkDotNet.Attributes.Jobs;
using JsonApiDotNetCore.Configuration;
using JsonApiDotNetCore.Internal;
using JsonApiDotNetCore.Managers.Contracts;
using JsonApiDotNetCore.Models;
using JsonApiDotNetCore.Services;
using Microsoft.AspNetCore.Http.Internal;
Expand All @@ -21,14 +22,14 @@ public class QueryParser_Benchmarks {
private const string DESCENDING_SORT = "-" + ATTRIBUTE;

public QueryParser_Benchmarks() {
var controllerContextMock = new Mock<IControllerContext>();
controllerContextMock.Setup(m => m.RequestEntity).Returns(new ContextEntity {
var requestMock = new Mock<IRequestManager>();
requestMock.Setup(m => m.GetContextEntity()).Returns(new ContextEntity {
Attributes = new List<AttrAttribute> {
new AttrAttribute(ATTRIBUTE, ATTRIBUTE)
}
});
var options = new JsonApiOptions();
_queryParser = new BenchmarkFacade(controllerContextMock.Object, options);
_queryParser = new BenchmarkFacade(requestMock.Object, options);
}

[Benchmark]
Expand Down Expand Up @@ -58,8 +59,8 @@ private void Run(int iterations, Action action) {
// this facade allows us to expose and micro-benchmark protected methods
private class BenchmarkFacade : QueryParser {
public BenchmarkFacade(
IControllerContext controllerContext,
JsonApiOptions options) : base(controllerContext, options) { }
IRequestManager requestManager,
JsonApiOptions options) : base(requestManager, options) { }

public void _ParseSortParameters(string value) => base.ParseSortParameters(value);
}
Expand Down
98 changes: 49 additions & 49 deletions benchmarks/Serialization/JsonApiSerializer_Benchmarks.cs
Original file line number Diff line number Diff line change
@@ -1,49 +1,49 @@
using System.Collections.Generic;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Attributes.Exporters;
using JsonApiDotNetCore.Builders;
using JsonApiDotNetCore.Configuration;
using JsonApiDotNetCore.Internal.Generics;
using JsonApiDotNetCore.Models;
using JsonApiDotNetCore.Serialization;
using JsonApiDotNetCore.Services;
using Moq;
using Newtonsoft.Json.Serialization;

namespace Benchmarks.Serialization {
[MarkdownExporter]
public class JsonApiSerializer_Benchmarks {
private const string TYPE_NAME = "simple-types";
private static readonly SimpleType Content = new SimpleType();

private readonly JsonApiSerializer _jsonApiSerializer;

public JsonApiSerializer_Benchmarks() {
var resourceGraphBuilder = new ResourceGraphBuilder();
resourceGraphBuilder.AddResource<SimpleType>(TYPE_NAME);
var resourceGraph = resourceGraphBuilder.Build();

var jsonApiContextMock = new Mock<IJsonApiContext>();
jsonApiContextMock.SetupAllProperties();
jsonApiContextMock.Setup(m => m.ResourceGraph).Returns(resourceGraph);
jsonApiContextMock.Setup(m => m.AttributesToUpdate).Returns(new Dictionary<AttrAttribute, object>());

var jsonApiOptions = new JsonApiOptions();
jsonApiOptions.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
jsonApiContextMock.Setup(m => m.Options).Returns(jsonApiOptions);

var genericProcessorFactoryMock = new Mock<IGenericProcessorFactory>();

var documentBuilder = new DocumentBuilder(jsonApiContextMock.Object);
_jsonApiSerializer = new JsonApiSerializer(jsonApiContextMock.Object, documentBuilder);
}

[Benchmark]
public object SerializeSimpleObject() => _jsonApiSerializer.Serialize(Content);

private class SimpleType : Identifiable {
[Attr("name")]
public string Name { get; set; }
}
}
}
//using System.Collections.Generic;
//using BenchmarkDotNet.Attributes;
//using BenchmarkDotNet.Attributes.Exporters;
//using JsonApiDotNetCore.Builders;
//using JsonApiDotNetCore.Configuration;
//using JsonApiDotNetCore.Internal.Generics;
//using JsonApiDotNetCore.Models;
//using JsonApiDotNetCore.Serialization;
//using JsonApiDotNetCore.Services;
//using Moq;
//using Newtonsoft.Json.Serialization;

//namespace Benchmarks.Serialization {
// [MarkdownExporter]
// public class JsonApiSerializer_Benchmarks {
// private const string TYPE_NAME = "simple-types";
// private static readonly SimpleType Content = new SimpleType();

// private readonly JsonApiSerializer _jsonApiSerializer;

// public JsonApiSerializer_Benchmarks() {
// var resourceGraphBuilder = new ResourceGraphBuilder();
// resourceGraphBuilder.AddResource<SimpleType>(TYPE_NAME);
// var resourceGraph = resourceGraphBuilder.Build();

// var jsonApiContextMock = new Mock<IJsonApiContext>();
// jsonApiContextMock.SetupAllProperties();
// jsonApiContextMock.Setup(m => m.ResourceGraph).Returns(resourceGraph);
// jsonApiContextMock.Setup(m => m.AttributesToUpdate).Returns(new Dictionary<AttrAttribute, object>());

// var jsonApiOptions = new JsonApiOptions();
// jsonApiOptions.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
// jsonApiContextMock.Setup(m => m.Options).Returns(jsonApiOptions);

// var genericProcessorFactoryMock = new Mock<IGenericProcessorFactory>();

// var documentBuilder = new DocumentBuilder(jsonApiContextMock.Object);
// _jsonApiSerializer = new JsonApiSerializer(jsonApiContextMock.Object, documentBuilder);
// }

// [Benchmark]
// public object SerializeSimpleObject() => _jsonApiSerializer.Serialize(Content);

// private class SimpleType : Identifiable {
// [Attr("name")]
// public string Name { get; set; }
// }
// }
//}
3 changes: 3 additions & 0 deletions docs/obsoletes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# For v5

* Anything to do with JsonApiContext, make it internal and fix anything related to it.
5 changes: 5 additions & 0 deletions markdownlint.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"MD033": {
"allowed_elements": [ "p", "img", "p" ]
}
}
11 changes: 7 additions & 4 deletions src/Examples/GettingStarted/Controllers/ArticlesController.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
using GettingStarted.Models;
using JsonApiDotNetCore.Configuration;
using JsonApiDotNetCore.Controllers;
using JsonApiDotNetCore.Internal.Contracts;
using JsonApiDotNetCore.Services;

namespace GettingStarted
{
public class ArticlesController : JsonApiController<Article>
{
public ArticlesController(
IJsonApiContext jsonApiContext,
IResourceService<Article> resourceService)
: base(jsonApiContext, resourceService)
IJsonApiOptions jsonApiOptions,
IResourceGraph resourceGraph,
IResourceService<Article> resourceService)
: base(jsonApiOptions, resourceGraph, resourceService)
{ }
}
}
}
11 changes: 7 additions & 4 deletions src/Examples/GettingStarted/Controllers/PeopleController.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
using GettingStarted.Models;
using JsonApiDotNetCore.Configuration;
using JsonApiDotNetCore.Controllers;
using JsonApiDotNetCore.Internal.Contracts;
using JsonApiDotNetCore.Services;

namespace GettingStarted
{
public class PeopleController : JsonApiController<Person>
{
public PeopleController(
IJsonApiContext jsonApiContext,
IResourceService<Person> resourceService)
: base(jsonApiContext, resourceService)
IJsonApiOptions jsonApiOptions,
IResourceGraph resourceGraph,
IResourceService<Person> resourceService)
: base(jsonApiOptions, resourceGraph, resourceService)
{ }
}
}
}
44 changes: 24 additions & 20 deletions src/Examples/GettingStarted/Properties/launchSettings.json
Original file line number Diff line number Diff line change
@@ -1,23 +1,27 @@
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:56042/",
"sslPort": 0
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:56042/",
"sslPort": 0
}
},
"GettingStarted": {
"commandName": "Project",
"launchBrowser": true
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"GettingStarted": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "http://localhost:49300/"
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Collections.Generic;
using JsonApiDotNetCore.Internal;
using JsonApiDotNetCore.Internal.Contracts;
using JsonApiDotNetCore.Models;

namespace GettingStarted.ResourceDefinitionExample
Expand All @@ -18,4 +19,4 @@ public ModelDefinition(IResourceGraph graph) : base(graph)
protected override List<AttrAttribute> OutputAttrs()
=> Remove(model => model.DontExpose);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
using GettingStarted.Models;
using JsonApiDotNetCore.Configuration;
using JsonApiDotNetCore.Controllers;
using JsonApiDotNetCore.Internal.Contracts;
using JsonApiDotNetCore.Services;

namespace GettingStarted.ResourceDefinitionExample
{
public class ModelsController : JsonApiController<Model>
{
public ModelsController(
IJsonApiContext jsonApiContext,
IResourceService<Model> resourceService)
: base(jsonApiContext, resourceService)
IJsonApiOptions jsonApiOptions,
IResourceGraph resourceGraph,
IResourceService<Model> resourceService)
: base(jsonApiOptions, resourceGraph, resourceService)
{ }
}
}
}
Loading