Concerns

Concerns allow to add behavior to a section of your web application by intercepting requests and responses. The framework allows any handler to be extended by using concerns. The following example will add a custom HTTP header to every response generated by the server:

public class CustomConcern : IConcern
{

    public IHandler Content { get; }

    public IHandler Parent { get; }

    public CustomConcern(IHandler parent, Func<IHandler, IHandler> contentFactory)
    {
        Parent = parent;
        Content = contentFactory(this);
    }

    public IAsyncEnumerable<ContentElement> GetContentAsync(IRequest request) => Content.GetContentAsync(request);
    
    public ValueTask PrepareAsync() => Content.PrepareAsync();

    public async ValueTask<IResponse?> HandleAsync(IRequest request)
    {
        var response = await Content.HandleAsync(request);
        
        if (response != null) 
        {
            response.Headers.Add("X-Custom-Header", "Custom Concern");
        }

        return response;
    }

}

public class CustomConcernBuilder : IConcernBuilder
{

    public IConcern Build(IHandler parent, Func<IHandler, IHandler> contentFactory)
    {
        return new CustomConcern(parent, contentFactory);
    }

}

var handler = Layout.Create()
                    .Index(Content.From("Hello World"))
                    .Add(new CustomConcernBuilder());

Host.Create()
    .Handler(handler)
    .Run();

The GenHTTP SDK uses the same mechanism to achieve functionality such as compression or support for CORS.

Share