F # - Объединить модули? - PullRequest
       5

F # - Объединить модули?

0 голосов
/ 24 апреля 2011

Сейчас я работаю над Entry Framework Code First Wrapper для F #, и мне было интересно, следует ли мне объединить все мои модули в один.

Взгляните на это:

module ManyNavProperty =
    let withMany (cfg:ManyNavPropertyInfo<'a,'b>) = cfg.WithMany()
    let withSeq expr (cfg:ManyNavPropertyInfo<'a,'b>) = cfg.WithSeq expr
    let withList expr (cfg:ManyNavPropertyInfo<'a,'b>) = cfg.WithList expr
    let withArray expr (cfg:ManyNavPropertyInfo<'a,'b>) = cfg.WithArray expr
    let withOptional (cfg:ManyNavPropertyInfo<'a,'b>) = cfg.WithOptional()
    let withOptionalProperty expr (cfg:ManyNavPropertyInfo<'a,'b>) = cfg.WithOptional expr
    let withRequired (cfg:ManyNavPropertyInfo<'a,'b>) = cfg.WithRequired()
    let withRequiredProperty expr (cfg:ManyNavPropertyInfo<'a,'b>) = cfg.WithRequiredProperty expr

module DependentNavProperty =
    let hasForeignKey expr (cfg:DependentNavPropertyInfo<'a>) = cfg.HasForeignKey expr

module CascadableNavProperty =
    let willCascadeOnDelete b (cfg:CascadableNavPropertyInfo) = cfg.WillCascadeOnDelete b

module EF =
    let entity<'a when 'a : not struct> (cfg:DbModelBuilder) = EntityInfo<'a>(cfg.Entity<'a>())
    let hasKey expr (cfg:EntityInfo<'a>) = cfg.HasKey expr
    let hasSeq expr (cfg:EntityInfo<'a>) = cfg.HasSeq expr
    let hasList expr (cfg:EntityInfo<'a>) = cfg.HasList expr 
    let hasArray expr (cfg:EntityInfo<'a>) = cfg.HasArray expr
    let hasOptional expr (cfg:EntityInfo<'a>) = cfg.HasOptional expr
    let hasRequired expr (cfg:EntityInfo<'a>) = cfg.HasRequried expr
    let toTable s (cfg:EntityInfo<'a>) = cfg.ToTable s

, что потребовало бы от меня вызова кода вроде:

override x.OnModelCreating (mb:DbModelBuilder) =
    let finished = ignore
    let entity = EF.entity<Author> mb

    entity
    |> EF.hasSeq <@ fun z -> z.Books @>
        |> ManyNavProperty.withRequiredProperty <@ fun z -> z.Author @>
            |> DependentNavProperty.hasForeignKey <@ fun z -> z.AuthorId @>
                |> CascadableNavProperty.willCascadeOnDelete true
    |> finished

Неужели использование такого количества модулей сбивает с толку пользователя? - Должен ли я поместить их все в один модуль или это разрушит обзор для пользователя?

Пример, в котором все функции размещены в одном модуле:

override x.OnModelCreating (mb:DbModelBuilder) =
    let finished = ignore
    let entity = EF.entity<Author> mb

    entity
    |> EF.hasSeq <@ fun z -> z.Books @>
        |> EF.withRequiredProperty <@ fun z -> z.Author @>
            |> EF.hasForeignKey <@ fun z -> z.AuthorId @>
                |> EF.willCascadeOnDelete true
    |> finished

1 Ответ

7 голосов
/ 24 апреля 2011

Это сложный вопрос проектирования.

Как правило, библиотеки F # обычно объединяют функции, которые работают с типом (например, list<T> или seq<T>), в отдельный модуль с именем, совпадающим с типом.(например, List.xyz и Seq.xyz).Это хорошо работает для распространенных типов, потому что пользователи учатся находить функции.

Однако для менее распространенных типов (например, вашей собственной библиотеки) может быть немного трудно обнаружить эти модули (особенно еслиТип не создается явно (но получается в результате некоторого вызова). Наличие одного имени модуля, а затем использование . для его изучения является довольно мощным.

Я бы, вероятно, предложил использовать вложенные модули.:

module EF =
  // common functions
  module Cascadable = 
    // CascadableNavProperty functions
  module Many = 
    // etc.

Пользователи могут найти все, начиная с EF. Они напишут что-то вроде:

entity
|> EF.hasSeq <@ fun z -> z.Books @>
  |> EF.Many.withRequiredProperty <@ fun z -> z.Author @>
    |> EF.Dependent.hasForeignKey <@ fun z -> z.AuthorId @>
      |> EF.Cascadable.willCascadeOnDelete true
|> finished
...