SaturnFramework / Saturn

Opinionated, web development framework for F# which implements the server-side, functional MVC pattern
https://saturnframework.org
MIT License
715 stars 109 forks source link

FS0708 #325

Open jkone27 opened 2 years ago

jkone27 commented 2 years ago

i am trying to extend a computation expression to add some custom behaviour, but then i get this error

  Program.fs(40, 9): [FS0708] This control construct may only be used if the computation expression builder defines a 'For' method
   let app = application {
        use_router(apiRouter)
        url("http://0.0.0.0:5000/")
        url("https://0.0.0.0:5005/")
        acme_bootstrap
        configure_app_configuration_json_vars
        logging (fun (logger : ILoggingBuilder) -> logger.ClearProviders())
        use_default_service_provider //<<<<FS0708
        services_config(configureServices)
    }

and here are my extensions


module SaturnExtensions =
    type ApplicationBuilder with
    [<CustomOperationAttribute("acme_bootstrap")>]
    member this.AcmeBootstrap(state : ApplicationState) =

        let mutable environment : IWebHostEnvironment = null

        let middleware (app : IApplicationBuilder) =
            environment <- Environment.getWebHostEnvironment(app)
            app

        let service (services : IServiceCollection) =
            services.BootstrapEndpointsWebApplication(
                environment,
                (Config.getConfiguration(services)),
                fun opt ->
                    opt.ApplicationInformation.ApplicationName <- "Acme.WebApi.Template.ApplicationName"
                    opt.ApplicationInformation.ApplicationGroup <- "Acme.WebApi.Template.ApplicationGroup"
            )

        {  state with
            ServicesConfig = service::state.ServicesConfig
            AppConfigs = middleware::state.AppConfigs
            }

    [<CustomOperationAttribute("use_current_directory_content_root")>] 
    member this.UseContentRoot(state : ApplicationState) =
        let config (webHostBuilder:IWebHostBuilder) =
            let dir = System.IO.Directory.GetCurrentDirectory()
            webHostBuilder.UseContentRoot(dir)

        {state with WebHostConfigs = config::state.WebHostConfigs}

    [<CustomOperationAttribute("configure_app_configuration_json_vars")>] 
    member this.ConfigureAppConfigurationJsonVars(state : ApplicationState) =

        let config (webHostBuilder:IWebHostBuilder) =
            webHostBuilder.ConfigureAppConfiguration(fun context config ->
                !config.AddJsonFile("appsettings.json")
                    .AddJsonFile($"appsettings.{context.HostingEnvironment.EnvironmentName}.json", true)
                    .AddEnvironmentVariables()
            )

        {state with WebHostConfigs = config::state.WebHostConfigs}

    [<CustomOperationAttribute("use_default_service_provider")>] 
    member this.UseDefaultServiceProvider(state : ApplicationState) =

        let config (webHostBuilder:IWebHostBuilder) =

            webHostBuilder.UseDefaultServiceProvider(fun context options ->
                let isDevelopment = context.HostingEnvironment.IsDevelopment()
                options.ValidateScopes <- isDevelopment
                options.ValidateOnBuild <- isDevelopment
                )

        {state with WebHostConfigs = config::state.WebHostConfigs}
jkone27 commented 2 years ago

i solved by passing the lambda to services_config, instead of the function itself

  let app = application {
        //...
        services_config (fun x -> configureServices x) // solved the issue !
    } 
jkone27 commented 2 years ago

i got the same compilation error using pipe_through within endpoints router CE

 error FS0708: This control construct may only be used if the computation expression builder defines a 'For' method [/Users/admin/Repositories/travix.dotnettemplates/Travix.WebApi.Template.FSharp/content/src/Travix.WebApi.Template.WebService/Travix.WebApi.Template.WebService.fsproj]

image

    let apiPipe = pipeline {
        set_header "X-Test" "text"
        }

i think the cause was using this in endpoints (as quoted in docs this doesnt work anymore)

not_found_handler (setStatusCode 404 >=> text "Api 404")