繁体   English   中英

我应该如何公开在f#中声明的全局词典,该词典将添加来自不同HttpModules的项?

[英]How should I expose a global Dictionary declared in f# that will have items added from different HttpModules?

我有一个在以下代码中声明的字典(格式化程序),该字典将在多个HttpModule中添加项。 一旦加载了这些,就不会再被写入。 公开此内容以便可以从任何.NET语言访问的最佳方法是什么? 我知道这似乎很la脚,看起来我应该让他们实现ToString(),但是应用程序的一部分要求字符串采用某种格式,并且我不希望客户端必须以特定于以下方式的方式实现ToString():我的应用程序。

module MappingFormatters
open System
open System.Collections.Generic

let formatters = new Dictionary<Type, obj -> string>();

let format item =

    let toDateTime (d:DateTime) =
        let mutable date = d;
        if (date.Kind) <> System.DateTimeKind.Utc then
            date <- date.ToUniversalTime()
        date.ToString("yyyy-MM-ddTHH:mm:00Z")

    let stripControlCharacters (str:string) =
        let isControl c = not (Char.IsControl(c))
        System.String( isControl |> Array.filter <| str.ToCharArray())

    let defaultFormat (item:obj) =
        match item with
        | :? string as str-> stripControlCharacters(str)
        | :? DateTime as dte -> toDateTime(dte)
        | _ -> item.ToString()

    let key = item.GetType();
    if formatters.ContainsKey(key) then
        formatters.Item(key) item
    else
        defaultFormat item

如果问题只是关于语言互操作性的问题,那么我认为您应该将类​​型从

Dictionary<Type, obj -> string>

Dictionary<Type, Func<obj, string> >

然后您应该处于良好状态。

经过研究。 我决定创建一个名为MappingFormatters的类型,以容纳添加格式化程序的方法。 客户端不需要调用它,但是我的f#代码将调用它。 我相信这将使我能够使用常见的f#约定,同时为其他.net语言提供一种互操作性最小的方法。

module File1
open System


let mutable formatters = Map.empty<string, obj -> string>

let format (item:obj) = 

    let dateToString (d:DateTime) =
        let mutable date = d;
        if (date.Kind) <> System.DateTimeKind.Utc then
            date <- date.ToUniversalTime()
        date.ToString("yyyy-MM-ddTHH:mm:00Z")

    let stripCtrlChars (str:string) =
        let isControl c = not (Char.IsControl(c))
        System.String( isControl |> Array.filter <| str.ToCharArray())


    let key = item.GetType().AssemblyQualifiedName
    if Map.containsKey key formatters then
        Map.find key formatters item
    else
        match item with
        | :? DateTime as d -> dateToString d
        | _ -> stripCtrlChars (item.ToString())

let add (typ:Type) (formatter:obj -> string) =
    let contains = Map.containsKey
    let key = typ.AssemblyQualifiedName

    if not (formatters |> contains key) then
        formatters <- Map.add key formatter formatters

type MappingFormatters() = class
    let addLock = new obj()
    member a.Add (``type``:Type, formatter:Func<obj,string>) =
        lock addLock (fun () ->
            add ``type`` (fun x -> formatter.Invoke(x))
        )
end

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM