Streamline API surface #62
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This is the first part of a refactor that I hope will make our library even simpler to setup.
Rationale
There are starting to become a lot of moving parts that the user has to configure to get JSONAPI.NET integrated with their project:
IPluralizationServiceIModelManagerJsonApiFormatterEnableFilteringAttributeEnableSortingAttributeEnumerateQueryableAsyncAttributePascalizedControllerSelectorApiController-derived classesIMaterializerA lot of those components only fit together in one way, and trying to change their behavior will just break the system. For example, if you want filtering and sorting, you better remember to pass the same
IModelManagerinstance to each of the attributes, as well as to theJsonApiFormatter. And the action filters have to be registered in the right order, since filtering should be applied before sorting (and when we introduce paging, it absolutely must take place after sorting). And then there is the async enumerator, which has to run after all the other action filters.I felt like I could internalize a lot of stuff and only expose a simple API with sensible defaults that does all of that for you.
JsonApiConfiguration
There is now a fluent interface for configuring JSONAPI.NET called
JsonApiConfiguration. This object is responsible for setting up anHttpConfigurationobject the way we need it. The user can currently use this fluent interface to disable sorting and/or filtering, and to provide a pluralization service. It also lets them opt-in to the async queryable enumerator using a fluent extension method.JsonApiQueryableAttribute
I have combined the functionality of the filtering and sorting action filters into a new aggregate attribute called
JsonApiQueryableAttribute. I abstracted the old filters into new constructs calledIQueryableTransforms, and I pass those transforms to theJsonApiQueryableAttributeinsideJsonApiConfiguration.Apply(). When we implement pagination we can make that anIQueryableTransformas well.Autofac
I've taken on Autofac as a library dependency, and
JsonApiConfigurationuses it internally to manage the construction of our various components (JsonApiFormatter,ModelManager,JsonApiQueryableAttribute, etc.). At the moment the container I use for this purpose is not integrated with theHttpConfiguration's dependency resolver and will not interfere with controller instance DI.Still to do
JsonApiFormattercan be cleaned up to be internal and use a single constructor.IMetadataManager), then I believe we will need to take over setting the IDependencyResolver. If we do this, however, we will be forcing the user to use Autofac for resolving controller dependencies, which sounds pretty heavy-handed. At the very least we'd have to give them access to the ContainerBuilder for customization.ModelManagerandIModelManagercan be made internal.PascalizedControllerSelectorcan be made internal.Some links
Example JsonApiConfiguration
JsonApiConfiguration definition