Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generate inheritance information manually #1570

Closed
SebastianStehle opened this issue Aug 31, 2018 · 7 comments
Closed

Generate inheritance information manually #1570

SebastianStehle opened this issue Aug 31, 2018 · 7 comments

Comments

@SebastianStehle
Copy link
Contributor

Hi,

I have a typical application with multiple layers and separate data structures: DTOs in my Api Layer, Business Objects in my Domain Layer and so on.

But one part of my application is a rule engine, like "When X happens (Trigger) send a tweet (Action)". So far I use inheritance for the different actions and define this inheritance in my DTOs. I would like to add plugins for the actions and therefore I have to break the architecture here a little bit. The goal is to define Action Definitions in your plugin and everything else is generated from it, e.g.

public sealed class SlackAction : RuleAction
{
    [Required]
    [Display(Name = "Webhook Url", Description = "The slack webhook url.")]
    public Uri WebhookUrl { get; set; }

    [Required]
    [Display(Name = "Text", Description = "The text that is sent as message to slack.")]
    public string Text { get; set; }
}

The question is: How can I generate the inheritance definition for it? I am had a look to the interfaces like IOperationProcessor and so but I can just not find the right information.

@RicoSuter
Copy link
Owner

Inheritance is generated here:
https://github.com/RSuter/NJsonSchema/blob/master/src/NJsonSchema/Generation/JsonSchemaGenerator.cs#L659

More or less hard-coded... maybe we can provide add an extension point somehow? Maybe you can inherit from the generator class and modify/extend this?

Maybe we should wait until this pr which changes the allof generation is merged:
RicoSuter/NJsonSchema#733

@SebastianStehle
Copy link
Contributor Author

Thanks for your response. I also had a look to this class but there is no extension point.

Wait, I can just write a ITypeMapper, right?

@SebastianStehle
Copy link
Contributor Author

Mhm,

public class RuleActionSchema : ITypeMapper
{
	public Type MappedType ...

	public bool UseReference ...

	public Task GenerateSchemaAsync(JsonSchema4 schema, TypeMapperContext context)
	{
		var defaultSchema = context.JsonSchemaGenerator.GenerateAsync();
		
		Copy(defaultSchema, schema); // This sucks :(
		
		AddInheritedSchemas(schema);
	}
}

@RicoSuter
Copy link
Owner

RicoSuter commented Aug 31, 2018

Cant you just add the additional types to the document’s definition and reference the base schema in allof and maybe update the discriminator mappings of the base schema (in a document processor)?

@SebastianStehle
Copy link
Contributor Author

This was also my idea, but how can I find the correct schema in the document processor?

@RicoSuter
Copy link
Owner

The contest has a resolver which can resolve the generated schema for a type i think

@SebastianStehle
Copy link
Contributor Author

Thanks, it works:

public sealed class RuleActionProcessor : IDocumentProcessor
{
    public async Task ProcessAsync(DocumentProcessorContext context)
    {
        var schema = context.SchemaResolver.GetSchema(typeof(RuleAction), false);

        var discriminator = new OpenApiDiscriminator
        {
            JsonInheritanceConverter = new JsonInheritanceConverter("actionType"),
			PropertyName = "actionType"
        };

        schema.DiscriminatorObject = discriminator;
        schema.Properties["actionType"] = new JsonProperty
        {
            Type = JsonObjectType.String,
			IsRequired = true
        };

        foreach (var derived in ActionConfig.Actions)
        {
            await context.SchemaGenerator.GenerateAsync(derived, context.SchemaResolver);
        }
}
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants