Using log4net in F# as a singleton separate class - f#

I've seen a few posts about implementing log4net using C# and F# - but I am wanting to implement it as a singleton in a separate class ( so I can call from anywhere )
I am loosely following this post. I just think my translation from C# to F# is a bit behind.
I set up the log4net.config and run the following code at the start of my console app
namespace MyNamespace
open System.IO
open log4net.Config
module LoggerConfigure =
let configureLogging() =
FileInfo("log4net.config")
|> XmlConfigurator.Configure
|> ignore
The following ( from the link above ) is C# and I want it to be an F# class that can be called as a singleton.
private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
My primary quwation is - I'm a bit stuck converting that to an F# class. How do I do that?. Any ideas you have around the whole concept is appreciated as well.

There may be cases where a more sophisticated handling of singletons is needed, but I believe that standard global let declaration in an F# module would work well enough.
You just need to make sure that the configuration code is run before the log value is accessed, which you can do by making that call as part of the let binding that defines log:
module LoggerConfigure =
let configureLogging() =
FileInfo("log4net.config")
|> XmlConfigurator.Configure
|> ignore
log4net.LogManager.GetLogger
(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType)
let log = configureLogging()
Or if you prefer to put everything in a single expression:
module LoggerConfigure =
let log =
FileInfo("log4net.config") |> XmlConfigurator.Configure |> ignore
log4net.LogManager.GetLogger
(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType)

Related

F# non-static methods in modules

I am an absolute newbie to coding, but I need to modify a F# script. It always gives me the error "Method or object constructor 'x' is not static". I read that this might be due to the fact that I try to call a non-static method within a module, which is by default static. For example 'x' = Get.Axis():
module Primitives =
let axis1 = Zaber.Motion.Ascii.Device.GetAxis(1)
The manual only provides code in C#: var axis1 = device.GetAxis(1);
If I use static member instead of let, I'll get a 'unexpected keyword static in definition' error, although I checked the indentation as suggested in another question.
Assuming you're using the Zaber Motion Library, I think what you need to do is get an instance of a device first, instead of trying to access the class in a static context.
Their documentation includes an example of how to get a list of devices by opening a serial port:
open Zaber.Motion.Ascii
use connection = Connection.OpenSerialPort("COM3")
let deviceList = connection.DetectDevices()
match deviceList |> Seq.tryHead with // See if we got at least one device
| Some device ->
let axis = device.GetAxis(1)
// TODO: Do whatever you want with the axis here
| None ->
failwith "No Devices Found on COM3"

How to use Akka.Streams.*.ConcatMany in F#?

I want to create a flow that creates a new source (it will be a persistence query) out of incoming elements, and then flattens the results. Something like this simplified example:
var z = Source.Single(1).ConcatMany(i => Source.Single(i));
this code compiles and works as expected. My problem is that when I translate it to F#:
let z = Source.Single(1).ConcatMany(fun i -> Source.Single(i))
I get an error saying
This expression was expected to have type
'IGraph<SourceShape<'a>,Akka.NotUsed>'
but here has type
'Source<int,Akka.NotUsed>'
I think that the cause of that is that F# handles co/contravariance differently than C# and cannot simply convert these generic specializations (https://github.com/fsharp/fslang-suggestions/issues/162), but I cannot figure out a way to make a convertion between an int and a SourceShape<int>. Is it possible to convert this example to F#?
Looking at the code on GitHub, it appears that Source<TOut, TMat> is a direct implementation of IGraph, so you should just be able to cast it:
public sealed class Source<TOut, TMat> : IFlow<TOut, TMat>, IGraph<SourceShape<TOut>, TMat>
let z = Source.Single(1).ConcatMany(fun i -> Source.Single(i) :> IGraph<SourceShape<int>,Akka.NotUsed>)
I think the biggest difference between the C# and F# usage is that C# will automatically do the upcast for you.
One workaround that I found is to use Akkling.Streams wrapper library:
open Akkling.Streams
let x =
Source.singleton 1
|> Source.collectMap(fun x -> Source.singleton x)
the question how to do this without Akkling remains open.

Mocked Interface with NSubstitute on F# does not allow Returns

I have the following code:
open NSubstitute
type MyClass()=
let myObject = Substitute.For<IMyInterface>()
do myObject.MyProperty.Returns(true)
do myObject.MyMethod().Returns(true)
On "Returns" (both) I get the error that is not defined. The equivalent C# code works without issue. Adding |> ignore at the end of the do lines does not help. Am I missing something there?
I know you wrote that adding |> ignore at the end doesn't help, but this compiles on my machine:
type IMyInterface =
abstract MyProperty : bool with get, set
abstract member MyMethod : unit -> bool
open NSubstitute
type MyClass() =
let myObject = Substitute.For<IMyInterface>()
do myObject.MyProperty.Returns(true) |> ignore
do myObject.MyMethod().Returns(true) |> ignore
I attempted to infer the definition of IMyInterface from the question; did I get it wrong?
So after I tried the code (Mark Seemann's, as to avoid my C# class) on VS2012, fsi, through direct compilation with fsc and on VS2013, the issue is clearly a VS2012 problem. The code works correctly with the other three.
Not sure yet if it is using a different version of F#. Will need further investigation. But at least, for now, on VS2012 I can use:
do SubstituteExtensions.Returns(myObject.MyProperty, true) |> ignore
It works as well when I need to pass parameters to methods.

F# How to use an interface in a separate module

So I have been doing research on interfaces on F#. I have found these 2 articles on it. The MSDN and F# for fun and profit But unfortunately they are only skin deep.
UPDATED
here is my module with my interfaces
//open statements omitted for brevity
module DrawingInterfaces =
///gets a string representation of the SVG code representation of the object
type IRepresentable_SVG =
abstract member getSVGRepresenation : unit -> string
//other interfaces omitted for brevity
Now within the same namespace and physical folder also I have this:
type lineSet (x1off,x2off,y1off,y2off,x1,x2,y1,y2,rot,rotOff,count) =
//tons of member vals omitted for brevity
member val x1Start = x1 with get, set
interface DrawingInterfaces.IRepresentable_SVG with
member __.getSVGRepresenation() =
let mutable svg = ""
let mutable currentx1 = x1Start
svg
This used to give me 2 errors, before I was using the __. notation for the member. The first error was on the interface line. And a second on the member line.
The errors were respectively:
The type 'IRepresentable_SVG' is not defined
This instance member needs a parameter to represent the object being invoked.
I was able to fix the first one by changing the file order. Thanks to John Palmer.
The second one is nearly fixed./
After using the __ . notation I was able to get rid of the second error. However, now a new error pops up when I try to use type members in my interface implementation.
let mutable currentx1 = x1Start
x1Start shows as not being defined. I need to be able to use values stored in my other members within my implementation.
Let's first make it work and then point to your problems. I define below 2 separate modules in 2 separate .fs files within the same namespace Example for interface definition in module Example.DrawingInterfacesand interface implementation in module Example.UseInterface and also a console app that will use the interface from third (implicit) module Program. In my project correspondent code files are in the following order: DefInterface.fs, UseInterface,fs, Program.fs (I also made few idiomatic styling changes and more brevity omissions)
File: DefInterface.fs
namespace Example
module DrawingInterfaces =
type IRepresentable_SVG =
abstract member GetSVGRepresenation : unit -> string
File: UseInterface.fs
namespace Example
module UseInterface =
type LineSet (x1) =
member val X1Start = x1 with get, set
interface DrawingInterfaces.IRepresentable_SVG with
member __.GetSVGRepresenation() = "test" + " " + __.X1Start.ToString()
File: Program.fs
open Example
open System
[<EntryPoint>]
let main argv =
let lineSet = UseInterface.LineSet(5)
let example : DrawingInterfaces.IRepresentable_SVG = lineSet :> _
example.GetSVGRepresenation() |> printfn "%A"
lineSet.X1Start <- 10
example.GetSVGRepresenation() |> printfn "%A"
0
Compile, run and make sure it works.
Now to problems in your code:
first error message stems from the need to refer to the full implemented interface name in UseInterface.fs, which is Example.DrawingInterfaces.IRepresentable_SVG although as both modules belong to the same namespace the Example prefix may be omitted
second error message points to the need of using instance method in implementation class UseInterface.LineSet, which is achieved by prepending self-identifier __. to the method signature
Finally, notice the usage of your interface in Program.fs that imports namespace, provides module names for definition and implementation respectively, and also explicitly casts implementation LineSet to IRepresentable_SVG.
EDIT: I've added X1Start property to the original LineSet to show how it can be used from interface implementation per question author's request. Now self-id __. is more involved and probably using self. or even this. instead would make more sense.

Is there any way to use JavaScript attribute by default?

I just want somehow to say "I want all methods in this project use [JavaScript]"
Manually annotation every method is annoying
F# 3 lets you mark a module with the ReflectedDefinition attribute (aka [JavaScript] in WebSharper) which marks all the methods underneath.
See More About F# 3.0 Language Features:
(Speaking of uncommon attributes, in F# 3.0, the
[< ReflectedDefinition >] attribute can now be placed on modules and
type definitions, as a shorthand way to apply it to each individual
member of the module/type.)
I think Phil's answer is the way to go - when you can mark an entire module or type, it does not add too much noise and it also allows you to distinguish between server-side and client-side code in WebSharper.
Just for the record, the F# compiler is open-source and so someone (who finds this issue important) could easily create branch that would add an additional command line attribute to override the setting. I think this is just a matter of adding the parameter and then setting the default value of the reflect flag in check.fs (here is the source on GitHub).
At the moment, the main F# repository does not accept contributions that add new features (see the discussion here), but it is certainly a good way to send a feature request to the F# team :-)
If you annotate all your code with the JavaScript attribute, the WebSharper compiler will try to translate everything to JavaScript. A rule of thumb in WebSharper development is to separate server-side and client-side code, so you can simply annotate the module/class containing client-side code instead of every function/member if you're targeting .NET 4.5.
namespace Website
open IntelliFactory.WebSharper
module HelloWorld =
module private Server =
[<Rpc>]
let main() = async { return "World" }
[<JavaScript>] // or [<ReflectedDefinition>]
module Client =
open IntelliFactory.WebSharper.Html
let sayHello() =
async {
let! world = Server.main()
JavaScript.Alert <| "Hello " + world
}
let btn =
Button [Text "Click Me"]
|>! OnClick (fun _ _ ->
async {
do! sayHello()
} |> Async.Start)
let main() = Div [btn]
type Control() =
inherit Web.Control()
[<JavaScript>]
override __.Body = Client.main() :> _

Resources