使用F#开发ASP.NET Core应用程序

.NET Core 里的F#

在.NET Core刚发布时,就已经添加了对F#的支持。但因为当时F#组件还不完整,而一些依赖包并没有放在Nuget上,而是社区自己放到MyGet上,所以在使用dotnet new -l fs创建F#模板时需要在项目中自己添加NuGet.config文件以配置依赖包才能还原成功。

不过在1.0.1发布后改善了F#的模板,通过dotnet new创建F#项目已经不需要自己添加NuGet配置了。
使用dotnet new -l fs生成一个控制台应用程序:

在ASP.NET Core中使用F#

在使用dotnet new创建的C#项目中,可以选择web项目。但F#却只有ConsoleLib类型,没有web类型!

既然没有,那我们就将C#的web项目翻译成F#的项目。原始项目为用VS 2015创建的不包含验证的ASP.NET Core项目。

修改project.json文件

通过F#项目的project.json文件,我们可以发现需要修改以下几个地方。

dependencies节点增加F#的核心组件:

"Microsoft.FSharp.Core.netcore": "1.0.0-*"

在tools节点增加F#的编译工具:

"dotnet-compile-fsc": "1.0.0-*"

现在这些都还处于预览版的阶段,希望到时正式版时会提供F#的Web模板。

F#有一个比较麻烦的地方就是编译是按文件顺序的,如果在Visual Studio中,可以方便的在解决方案管理窗口里进行文件顺序变更。但在.NET Core项目中,则需要在project.json中指定。

buildOptions节点中,增加compilerNamefsc,添加compile节点,includeFiles指定所有需要编译的文件,最后的buildOptions节点如下:

"buildOptions": {
    "emitEntryPoint": true,
    "preserveCompilationContext": true,
    "compilerName": "fsc",
    "compile": {
      "includeFiles": [
        "Controllers/HomeControllers.fs",
        "Startup.fs",
        "Program.fs"
      ]
    }
  },

想了解project.json文件的作用,可以查看 "project.json reference" 。也可以参考博客园里的文章《project.json 这葫芦里卖的什么药》

源代码

修改完project.json文件,接下来将几个c#文件翻译成F#即可。这就不细说了,直接把代码贴上了。
Controllers/HomeControllers.fs

type HomeController() = 
    inherit Controller()

    member this.Index() = this.View()

    member this.About() =
        this.ViewData.["Message"] <- "Your application description page."
        this.View()

    member this.Contact() =
        this.ViewData.["Message"] <- "Your contact page.";
        this.View()

    member this.Error() = this.View()

Startup.fs

type Startup(env: IHostingEnvironment) =
    
    let builder = ConfigurationBuilder()
                    .SetBasePath(env.ContentRootPath)
                    .AddJsonFile("appsettings.json", true, true)
                    .AddJsonFile((sprintf "appsettings.%s.json" env.EnvironmentName), true)
                    .AddEnvironmentVariables();

    let configuration = builder.Build();    

    member this.ConfigureServices(services: IServiceCollection) =
        services.AddMvc() |> ignore


    member this.Configure(app:IApplicationBuilder, env:IHostingEnvironment,loggerFactory: ILoggerFactory) =
        loggerFactory
            .AddConsole(configuration.GetSection("Logging"))
            .AddDebug() 
            |> ignore

        if env.IsDevelopment() then
            app.UseDeveloperExceptionPage()
               .UseBrowserLink()
               |> ignore
        else
            app.UseExceptionHandler("/Home/Error") |> ignore

        app.UseStaticFiles() |> ignore

        app.UseMvc(fun routes -> routes.MapRoute("default","{controller=Home}/{action=Index}/{id?}") |> ignore)
        |>ignore

Program.fs

[<EntryPoint>]
let main argv =    

    let host = WebHostBuilder()
                    .UseKestrel()
                    .UseContentRoot(Directory.GetCurrentDirectory())
                    .UseIISIntegration()
                    .UseStartup<Startup>()
                    .Build()

    host.Run()
    0

完整的代码在此:https://github.com/lhysrc/fs-aspnetcore-demo,有兴趣的同学可以下载试试。

记得如果添加了F#源代码文件,需要将文件路径添加到project.json - buildOptions - includeFiles中。

结语

虽然可以用,但现在用F#进行ASP.NET Core的开发体验还不是很好。但只要.NET Core支持F#,相信这些工具方面的应该很快就会跟上。

当我把这个demo传上github,我发现其实已经有F#的ASP.NET Core模板了。😭不过是基于yo的,,项目地址:https://github.com/OmniSharp/generator-aspnet


本文发表于博客园。 转载请注明源链接:http://www.cnblogs.com/hjklin/p/fs-aspnetcore.html

posted @ 2016-10-18 15:49  忽见客来  阅读(4928)  评论(13编辑  收藏  举报