{"id":24716749,"url":"https://github.com/baylorrae/lightservice","last_synced_at":"2025-03-22T09:21:10.460Z","repository":{"id":10776495,"uuid":"13042609","full_name":"BaylorRae/LightService","owner":"BaylorRae","description":"Implementing functional style in C#","archived":false,"fork":false,"pushed_at":"2013-09-23T17:54:20.000Z","size":316,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-01-27T09:14:02.942Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/BaylorRae.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-09-23T17:47:27.000Z","updated_at":"2015-06-26T22:16:08.000Z","dependencies_parsed_at":"2022-09-11T16:01:21.705Z","dependency_job_id":null,"html_url":"https://github.com/BaylorRae/LightService","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BaylorRae%2FLightService","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BaylorRae%2FLightService/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BaylorRae%2FLightService/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BaylorRae%2FLightService/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/BaylorRae","download_url":"https://codeload.github.com/BaylorRae/LightService/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244932953,"owners_count":20534263,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-01-27T09:14:05.604Z","updated_at":"2025-03-22T09:21:10.405Z","avatar_url":"https://github.com/BaylorRae.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Light Service in C# \n\nI watched Attila Domokos' talk on [Simple and Elegant Rails Code with Functional\nStyle] where he introduced [Light Service]. The concept immediately captured my\ninterest and I thought it would be a fun exercise to rewrite it in C#.\n\n## Things worth noting\n\n- It supports static contexts which result in compile errors and auto\n  completion.\n- Logic can be spread out into multiple classes to simplify code and ease\n  testing.\n\n## LightService terms\n\n- **Contexts** are basically Value objects that store data.\n- **Organizers** invoke an array of actions and create a Context that is shared\n  among the Actions.\n- **Actions** take the information from the context, manipulate the data inside\n  it, and pass it to the next action.\n\n## Example\n\n```c#\n// CONTROLLER\nnamespace LightServiceDemo.Controllers {\n  public class OrdersController : Controller {\n    public ActionResult Index() {\n\n      // create order and calculate its tax\n      Models.Order order = new Models.Order() { SubTotal = 55 };\n      Contexts.OrderContext result = Organizers.CalculatesOrderTax.ForOrder(order);\n\n      ViewBag.Order = result.Order;\n      return View();\n\n    }\n  }\n}\n\n// CONTEXT\nnamespace LightServiceDemo.Contexts {\n  public class OrderContext : LightService.Context {\n    public Models.Order Order { get; set; }\n    public int TaxPercentage { get; set; }\n  }\n}\n\n// ORGANIZER\nnamespace LightServiceDemo.Organizers {\n  public class CalculatesOrderTax : LightService.Organizer\u003cOrderContext\u003e {\n\n    public static OrderContext ForOrder(Models.Order order) {\n      // create a new context with the order\n      // and call the relevant actions\n      return With(ContextWithOrder(order)).Reduce(Actions());\n    }\n\n    private static OrderContext ContextWithOrder(Models.Order order) {\n      return new OrderContext() { Order = order };\n    }\n\n    private static LightService.IAction\u003cOrderContext\u003e[] Actions() {\n      return new LightService.IAction\u003cOrderContext\u003e[] {\n        new Actions.CalculateTax(),\n        new Actions.AddTaxToSubTotal()\n      };\n    }\n\n  }\n}\n\n// ACTIONS\nnamespace LightServiceDemo.Actions {\n  public class CalculateTax : LightService.IAction\u003cOrderContext\u003e {\n\n    public OrderContext Executed(OrderContext context) {\n      context.TaxPercentage = 7;\n      return context;\n    }\n\n  }\n}\n\nnamespace LightServiceDemo.Actions {\n  public class AddTaxToSubTotal : LightService.IAction\u003cOrderContext\u003e {\n\n    public OrderContext Executed(OrderContext context) {\n      Order order = context.Order;\n      order.SubTotal += TaxAmount(order.SubTotal, context.TaxPercentage);\n\n      context.Order = order;\n      return context;\n    }\n\n    private decimal TaxAmount(decimal subTotal, int taxPercentage) {\n      return subTotal * (taxPercentage / (decimal) 100.0);\n    }\n  }\n}\n```\n\n## TODO\n\n- Add way to break early from the loop of calling Actions.\n  - this needs to be done with failing or succeeding early\n\n[Simple and Elegant Rails Code with Functional Style]: http://www.adomokos.com/2013/06/simple-and-elegant-rails-code-with.html\n[Light Service]: https://github.com/adomokos/light-service\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbaylorrae%2Flightservice","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbaylorrae%2Flightservice","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbaylorrae%2Flightservice/lists"}