.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#却只有Console和Lib类型,没有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
节点中,增加compilerName
为fsc
,添加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模板了。