comments
A new Visual Studio template has been added to the latest Visual Studio installer called "Self-Hosted Client-Server Application," and you can use this template to build OWIN-based self-hosted applications that can be deployed via an .exe file and without requiring an installed web container (IIS, etc.) on the serving machine.
The following code shows embedding a given sitelet (Site.MainSitelet) into an OWIN container and starting it:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
module SelfHostedServer =
open global.Owin
open Microsoft.Owin.Hosting
open Microsoft.Owin.StaticFiles
open Microsoft.Owin.FileSystems
open IntelliFactory.WebSharper.Owin
[<EntryPoint>]
let Main = function
| [| rootDirectory; url |] ->
use server = WebApp.Start(url, fun appB ->
appB.UseStaticFiles(
StaticFileOptions(
FileSystem = PhysicalFileSystem(rootDirectory)))
.UseSitelet(rootDirectory, Site.MainSitelet)
|> ignore)
stdout.WriteLine("Serving {0}", url)
stdin.ReadLine() |> ignore
0
| _ ->
eprintfn "Usage: OWIN1 ROOT_DIRECTORY URL"
1The OWIN machinery to make this work has been released as a new WebSharper.Owin NuGet package as well. The new Visual Studio template contains this boilerplate code, takes care of fetching the dependent OWIN packages, and calls the generated OWIN container .exe with the right arguments to host your sitelets easily.
Work to add this new WebSharper project template to the MonoDevelop/Xamarin Studio integration is underway.
Let us know what you think and happy coding!







Great. This is simpler than the previous WebSharper.WebApi version, and with UseCustomSitelet I can now control whether to serve .js (for debug) or .min.js (for release), which is good.
The comments for UseCustomSitelet say:
... Allows a more customized setup than the previous methods, for example running a Sitelet whose code isn't located in the "bin" subfolder of the root folder ...
I am using this code in an Azure 'worker role', and that means all the DLLs are in the 'webRoot' folder itself (rather than in a 'bin' subfolder, as would be the case with a 'web role'), so this comment caught my eye. But, unless I am missing a trick, the only way I could achieve this was to create another Create overload, which takes a 'binFolder':
type Options with static member Create (webRoot, binFolder) = let meta = M.Info.LoadFromBinDirectory binFolder Options.Create(meta) .WithServerRootDirectory(webRoot)But this requires me to duplicate the code for LoadFromWebRoot (and DiscoverAssemblies), since these are not public. Is there a better way?
Anyway, it all seems to work.
Thank you.
David.