Skip to content

Commit fd6ad28

Browse files
Merge pull request #14 from FabianGosebrink/improved-linkservice
improved linkhelper
2 parents 231fffe + 4a15200 commit fd6ad28

File tree

2 files changed

+29
-66
lines changed

2 files changed

+29
-66
lines changed

SampleWebApiAspNetCore/Program.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1+
using Microsoft.AspNetCore.Mvc;
12
using Microsoft.AspNetCore.Mvc.ApiExplorer;
3+
using Microsoft.AspNetCore.Mvc.Infrastructure;
4+
using Microsoft.AspNetCore.Mvc.Routing;
25
using Microsoft.EntityFrameworkCore;
36
using Microsoft.Extensions.Options;
47
using Newtonsoft.Json.Serialization;
@@ -25,8 +28,12 @@
2528

2629
builder.Services.AddSingleton<ISeedDataService, SeedDataService>();
2730
builder.Services.AddScoped<IFoodRepository, FoodSqlRepository>();
31+
builder.Services.AddScoped(typeof(ILinkService<>), typeof(LinkService<>));
2832
builder.Services.AddTransient<IConfigureOptions<SwaggerGenOptions>, ConfigureSwaggerOptions>();
2933

34+
builder.Services.AddSingleton<IActionContextAccessor, ActionContextAccessor>();
35+
builder.Services.AddSingleton<IUrlHelperFactory, UrlHelperFactory>();
36+
3037
builder.Services.AddRouting(options => options.LowercaseUrls = true);
3138
builder.Services.AddVersioning();
3239

SampleWebApiAspNetCore/Services/LinkService.cs

Lines changed: 22 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -2,42 +2,27 @@
22
using SampleWebApiAspNetCore.Models;
33
using SampleWebApiAspNetCore.Helpers;
44
using System.Reflection;
5+
using Microsoft.AspNetCore.Mvc.Routing;
6+
using Microsoft.AspNetCore.Mvc.Infrastructure;
57

68
namespace SampleWebApiAspNetCore.Services
79
{
8-
[AttributeUsage(AttributeTargets.Method)]
9-
public class LinkCollectionAttribute : Attribute
10-
{
11-
private string name;
12-
13-
public LinkCollectionAttribute(string name)
14-
{
15-
this.name = name;
16-
}
17-
}
18-
19-
[AttributeUsage(AttributeTargets.Method)]
20-
public class HateoasAttribute : Attribute
21-
{
22-
23-
}
24-
2510
public class LinkService<T> : ILinkService<T>
2611
{
2712
private readonly IUrlHelper _urlHelper;
2813

29-
public LinkService(IUrlHelper urlHelper)
14+
public LinkService(IUrlHelperFactory urlHelperFactory, IActionContextAccessor actionContextAccessor)
3015
{
31-
_urlHelper = urlHelper;
16+
_urlHelper = urlHelperFactory.GetUrlHelper(actionContextAccessor.ActionContext);
3217
}
3318

3419
public List<LinkDto> CreateLinksForCollection(QueryParameters queryParameters, int totalCount, ApiVersion version)
3520
{
36-
Type myType = (typeof(T));
37-
MethodInfo[] methods = myType.GetMethods();
21+
Type controllerType = (typeof(T));
22+
MethodInfo[] methods = controllerType.GetMethods();
3823

3924
var links = new List<LinkDto>();
40-
var getAllMethodName = GetGetAllMethod(methods);
25+
var getAllMethodName = GetMethod(methods, typeof(HttpGetAttribute), 0);
4126

4227
// self
4328
links.Add(new LinkDto(_urlHelper.Link(getAllMethodName, new
@@ -95,21 +80,21 @@ public object ExpandSingleFoodItem(object resource, int identifier, ApiVersion v
9580
{
9681
var resourceToReturn = resource.ToDynamic() as IDictionary<string, object>;
9782

98-
var links = GetLinks(identifier, version);
83+
var links = GetLinksForSingleItem(identifier, version);
9984

10085
resourceToReturn.Add("links", links);
10186

10287
return resourceToReturn;
10388
}
10489

10590

106-
private IEnumerable<LinkDto> GetLinks(int id, ApiVersion version)
91+
private IEnumerable<LinkDto> GetLinksForSingleItem(int id, ApiVersion version)
10792
{
10893
Type myType = (typeof(T));
10994
MethodInfo[] methods = myType.GetMethods();
11095
var links = new List<LinkDto>();
11196

112-
var getLink = _urlHelper.Link(GetGetSingleMethod(methods), new { version = version.ToString(), id = id });
97+
var getLink = _urlHelper.Link(GetMethod(methods, typeof(HttpGetAttribute), 1), new { version = version.ToString(), id = id });
11398
links.Add(new LinkDto(getLink, "self", "GET"));
11499

115100
var deleteLink = _urlHelper.Link(GetMethod(methods, typeof(HttpDeleteAttribute)), new { version = version.ToString(), id = id });
@@ -133,62 +118,33 @@ private IEnumerable<LinkDto> GetLinks(int id, ApiVersion version)
133118
return links;
134119
}
135120

136-
private string GetMethod(MethodInfo[] methods, Type type)
137-
{
138-
var method = methods.Where(m => m.GetCustomAttributes(type, false).Length > 0).ToArray().FirstOrDefault();
139-
140-
if (method is null)
141-
{
142-
return null;
143-
}
144-
145-
return method.Name;
146-
}
147-
148-
private string GetGetSingleMethod(MethodInfo[] methods)
121+
private string GetMethod(MethodInfo[] methods, Type type, int routeParamsLength = 0)
149122
{
150-
var getMethods = methods.Where(m => m.GetCustomAttributes(typeof(HttpGetAttribute), false).Length > 0).ToArray();
123+
var filteredMethods = methods.Where(m => m.GetCustomAttributes(type, false).Length > 0).ToArray();
151124

152-
if (getMethods.Length == 0)
125+
if (filteredMethods.Length == 0)
153126
{
154-
return null;
127+
return "";
155128
}
156129

157-
foreach (var getMethod in getMethods)
130+
if (routeParamsLength == 0)
158131
{
159-
var routeAttribs = getMethod.GetCustomAttributes(typeof(RouteAttribute));
132+
var toReturn = filteredMethods.FirstOrDefault();
160133

161-
if(routeAttribs.Count() == 1)
162-
{
163-
return getMethod.Name;
164-
}
134+
return toReturn is not null ? toReturn.Name : "";
165135
}
166136

167-
168-
return null;
169-
}
170-
171-
private string GetGetAllMethod(MethodInfo[] methods)
172-
{
173-
var getMethods = methods.Where(m => m.GetCustomAttributes(typeof(HttpGetAttribute), false).Length > 0).ToArray();
174-
175-
if (getMethods.Length == 0)
137+
foreach (var method in filteredMethods)
176138
{
177-
return null;
178-
}
139+
var routeAttribs = method.GetCustomAttributes(typeof(RouteAttribute));
179140

180-
foreach (var getMethod in getMethods)
181-
{
182-
var routeAttribs = getMethod.GetCustomAttributes(typeof(RouteAttribute));
183-
184-
if (routeAttribs.Count() == 0)
141+
if (routeAttribs.Count() == routeParamsLength)
185142
{
186-
return getMethod.Name;
143+
return method.Name;
187144
}
188145
}
189146

190-
191-
return null;
147+
return "";
192148
}
193149
}
194150
}

0 commit comments

Comments
 (0)