Я постепенно переключаюсь на F # для многих моих домашних проектов, но я немного озадачен тем, как соединять вместе готовые приложения, и, в частности, сквозные вопросы.
В C #, если я хочу регистрировать вещи, я бы использовал внедрение зависимостей для передачи ILogger в каждый класс, и тогда это можно легко и просто назвать из кода. В своих тестах я могу проверить, что для конкретной ситуации записываются журналы, передав имитирование и проверяя его.
public class MyClass
{
readonly ILogger _logger;
public MyClass(ILogger logger)
{
_logger = logger;
}
public int Divide(int x, int y)
{
if(y == 0)
{
_logger.Warn("y was 0");
return 0;
}
return x / y;
}
}
В F # я использую модули гораздо больше, поэтому вышеприведенное станет
module Stuff
let divde x y =
match y with
| 0 -> 0
| _ -> x / y
Теперь, если бы у меня был модуль, называемый Logging, я мог бы просто открыть его и использовать функцию log оттуда в случае, если y равно 0, но как бы я внедрил это для модульного тестирования?
Я мог бы заставить каждую функцию взять функцию журнала (string -> unit), а затем использовать частичное приложение, чтобы соединить их, но это кажется огромной работой, как если бы я создал новую функцию, которая оборачивает реальный вызов внутри входящий звонок. Есть ли какой-то конкретный шаблон или немного F #, который мне не хватает, который может это сделать?
(Я видел функцию kprintf, но до сих пор не знаю, как бы вы указали функцию для различных тестовых сценариев, используя конкретную реализацию для всего приложения)
Точно так же, как бы вы заглушили хранилище, которое извлекало данные? Нужно ли создавать какой-либо класс и устанавливать на него функции CRUD, или есть способ внедрить, какие модули вы открываете (кроме #define)