OpenAPI.NET.OData icon indicating copy to clipboard operation
OpenAPI.NET.OData copied to clipboard

Refactor the whole project

Open xuzhg opened this issue 5 years ago • 2 comments

Short summary (3-5 sentences) describing the issue.

Recently, I got a lot of requirements, for example

  1. I don't want to expand on certain element
  2. I don't need this operation
  3. I need this ...
  4. etc..

Yes, we can meet all of these by modifying the codes, by adding settings, etc. However, i'd think maybe it's time to refactor it in the next major release.

Design

I'd like to use the Dependency Injection to allow customer to customize the converting process.

We need figure out the working flow from OData to OpenAPI. The process steps are certain, at each step, we can create a service to work on it.

Services

We need figure out the services used during converting. for example:

  1. we should have a OData path provider service
  2. we should have a OpenApi path generator service
  3. We should have a convert engine

Extension methods

I think we need

public static IServiceCollection UseOpenApiOData(IServiceCollection services)
{
        services.AddSingleton<IOpenApiODataConverter>(); // converter or generator
        services.AddSingleton<IODataPathProvider>();
        services.AddSingleton<IODataOpenApiPathHandler>();
        services.AddSingleton<IODataOpenApiOperationHandler>();
.....
        service.AddSingleton<ODataOpenApiOptions>();
        return services;
}

Usage

  1. you can create the OpenApiODataConverter instance (normal way)
  2. you can retrieve it from service provider.
IServiceCollection services= new ServiceCollection();
services.UserOpenApiOData();
IServiceProvider sp = services.CreateServiceProvider();
IOpenApiODataConverter converter = sp.GetService<IOpenApiODataConverter>();
...

Advantage

  1. It can be used in the ASP.NET Core pipeline, for example we can create a middleware to generate the OpenAPI description for a OData service.

  2. It can support to customize the converting. For example, we can replace a certain service using customized service.

xuzhg avatar Jun 03 '20 18:06 xuzhg

This library could be useful to us and we also have the need to customize the generation replace services.

However, the way you're describing it sounds more like service locator pattern, which is more commonly considered an anti-pattern.

In my understanding, in pure dependency injection, you would inject the services (usually as constructor parameters), not the service provider. Using the service provider makes it more like service locator. The main drawback of service locator is that it's hard to figure out what other services a class depends on. So if Operation handler depends on Path hander, then it's much more obvious if Operation handler receives IODataOpenApiPathHandler as constructor parameter. Then there can be a separate "activator" or "factory" class which constructs the services, possibly making use of the dependency injection library and service provider.

jukkahyv avatar Apr 29 '21 11:04 jukkahyv

In general, making substantial breaking changes to the API surface of a library makes it less useful to Microsoft product teams consuming it, who simply can't rewrite their code to consume new, disruptive changes.

This simply stops us from consuming the new version and leaves us stuck on legacy versions.

Unless there is overwhelming new value, we should take the hit that the API surface which exists when a library becomes popular is the API surface for the forseeable future. The idea that the existence of major versions means it's OK to regularly make breaking change is a fallacy as a consumer.

garethj-msft avatar Apr 25 '22 20:04 garethj-msft