Closed
Description
We currently provide shortcut definitions for various interfaces and classes (service, repo, definition) when the ID type is int
. The proposed plan is to remove these extra types for the following reasons:
- The type
int
is not the obviously most commonly used or preferred key type. More common for SQL databases arelong
orGUID
. The most commonly used key type for MongoDB isstring
. So in general,int
doesn't deserve the special attention it gets today. - It complicates IoC container setup and resolving of types. This affects both performance and debuggability. For example, when a resource service asks for a repository instance, we first check if the key type is
int
and then prefer the single-parameter interface to resolve from the IoC container, falling back to the double-parameter interface (see here). This works fine, as long asRepository<TResource>
always inherits fromRepository<TResource, TId>
, which is not something JADNC can enforce. Likewise, when the developer forgets to make the single-parameter class implement the required interfaces, we silently resolve the wrong type. These problems are hard to diagnose. Finally, Resharper suggests "you can inject interface of base type" in constructor signatures (replacingIGetAllService<Article>
withIGetAllService<Article, int>
), which defeats the whole purpose of having these shortcut interfaces in the first place. - Given there are now two implementations for everything, extending them requires duplicate work. This can often be solved using inheritance, but not in all cases.
Given the above, we believe that being explicit on the key type is the overall better choice here. Note this is a breaking change. For example, users of JADNC will need to rewrite their controller from:
public sealed class TodoItemsController : JsonApiController<TodoItem>
{
public TodoItemsController(IJsonApiOptions options, ILoggerFactory loggerFactory,
IResourceService<TodoItem> resourceService)
: base(options, loggerFactory, resourceService)
{
}
}
to:
public sealed class TodoItemsController : JsonApiController<TodoItem, int>
// ^^^
{
public TodoItemsController(IJsonApiOptions options, ILoggerFactory loggerFactory,
IResourceService<TodoItem, int> resourceService)
// ^^^
: base(options, loggerFactory, resourceService)
{
}
}