Using an external lib as a module

Topics: Customizing Orchard, Writing modules
Jan 9, 2014 at 11:42 PM
Hi guys,

I have been involved in the community for a while, but I didn't write anything here yet, so here I go: I'm looking forward to use FSharp with Orchard, since Orchard is designed for using CSharp as a main language I will keep FSharp for my private modules (in order to take adventage of its goodness like: type providers, sintax, pattern matching...) The approach that I would take is to use it from another library, and to use the CSharp module as a wrapper. So, the process should be like using an external CSharp library.

I would start by telling orchard how to discover my controllers, I tried a few ways, including ControllerBuilder.Current.DefaultNamespaces.Add("MyCSharpLib.Controllers") But it doesn't work, would be nice if someone could point me in the right direction.

Thanks
Jan 14, 2014 at 11:13 PM
Anyone? Did someone try to use a CSharp lib as a module?
Developer
Jan 14, 2014 at 11:22 PM
I've never heard of anyone with a similar approach. Have you explored the idea of having an F# module?

Using an F# lib just as a library should work without problems. Not sure about registering it as a module though. The topics you could explore are (there are corresponding services in Orchard): extension loading (search ExtensionLoader), controller activation (not sure where this is...).
Jan 15, 2014 at 3:05 PM
Hi Piedone,
First of all, thanks for replying me :)

I would like to use the approach of using FSharp directly as a module, but since Orchard is configured to work with CSharp by default, somehow I have to tell Orchard that it should work with FSharp too and I don't see how to tell that to Orchard without changing the Core or using another module just for that, Orchard detects the module because of the file structure but it doesn't react to any event (e.g. Activated). BTW seems like a convention to use a wrapper CSharp project when working with FSharp in ASP.NET MVC too (be aware that FSharp project doesn't support folder structure by default)

I will try to register the lib as a module with the topics that you point me out, but seems weird to me that nobody tried to register a CSharp lib as a module before

Thanks
Jan 15, 2014 at 3:28 PM
Just figured out that actually it is reacting to the events, it even created the migration!
I will keep looking to add the controllers. :)
Developer
Jan 15, 2014 at 3:52 PM
Keep us posted then :-).

If to make using a purely F# module (F# project if) work needs modification to the core than it's also something worth exploring. If you can make it work please do it in a fork so we can take a look at it. It might be worth thinking about making the logic (whatever it be, I don't know this part of Orchard) that deals with the module processing and compilation extensible or at least support F# OOTB.

I don't know however how you can use the various Orchard services from Orchard. If you can call into classes and interfaces then it would work.
Jan 16, 2014 at 5:06 AM
At the end I managed to get all working as a module without changing anything in the core, adding FSharp.Core assembly to the bin directory on Orchard.Web should be enough, although DynamicCompilation is not working. But it isn't a big deal, by compiling the lib again when something changes, Orchard will pick the new assembly automatically.

In the following days (hopefully tomorrow) I will make a blog post about it. :-)
Developer
Jan 16, 2014 at 10:21 AM
Nice!
Jan 17, 2014 at 4:52 PM
This is becoming difficult, I thought that everything should work well (I sorted out a lot of problems) but now I'm having another problem creating the Record.

In FSharp the concept of abstract auto property doesn't exist so I have to explicitly create the back storage, but when I assign it to the field seems like the compiler creates a new one and since it is not private (and I don't have access to it) the NHibernate proxy fails to create the mapping.

Here is a gist with a sample, for MapRecord2 it works (but I don't have the back field storage so it's useless) https://gist.github.com/jmgomez/8476420
With the new InfoPart it shouldn't be any problem but accessing record is a must.

So I have to work around somehow telling NHibernate how the mapping is for my record. I don't know very well how nhibernate works with Orchard, but here is a similar problem:
http://stackoverflow.com/questions/741489/ignore-public-internal-fields-for-nhibernate-proxy

So, the question is if there is a way to cancel the proxy validator for my Record. And if so, can I configure it from my module?

Thanks!
Developer
Jan 17, 2014 at 5:00 PM
You can implement ISessionInterceptor to interact with NHibernate at a lower level.
Jan 17, 2014 at 8:07 PM
At the end I implemented ISessionConfigurationEvents

Thanks :)
Jan 18, 2014 at 2:40 PM
Here is a blog post in case that you're interested :) http://jmgomez.me/using-fsharp-with-orchardcms