2
comments
on 11/13/2014 3:18 PM

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"
            1

The 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':

1
2
3
4
5
    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.

By on 11/17/2014 11:49 AM ()

Indeed, this is an oversight in the public API; thanks for pointing it out! I will add methods and optional arguments to Options.Create and IAppBuilder extensions to address this. You can expect it to be released in the coming days.

By on 11/20/2014 3:38 AM ()
IntelliFactory Offices Copyright (c) 2011-2012 IntelliFactory. All rights reserved.
Home | Products | Consulting | Trainings | Blogs | Jobs | Contact Us | Terms of Use | Privacy Policy | Cookie Policy
Built with WebSharper