{"id":19175472,"url":"https://github.com/jzo001/forge.invoker","last_synced_at":"2026-06-11T20:31:29.854Z","repository":{"id":62712547,"uuid":"561948664","full_name":"JZO001/Forge.Invoker","owner":"JZO001","description":"Event delegate execution helper library","archived":false,"fork":false,"pushed_at":"2024-01-16T23:41:43.000Z","size":14,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-01-04T01:54:45.977Z","etag":null,"topics":["csharp","delegate","delegates","event","exception-handling","subscribers"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/JZO001.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-11-04T21:44:21.000Z","updated_at":"2023-01-13T15:36:24.000Z","dependencies_parsed_at":"2024-11-09T10:23:49.456Z","dependency_job_id":"3c35d7f0-9555-49c1-9690-850e6c1564fc","html_url":"https://github.com/JZO001/Forge.Invoker","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JZO001%2FForge.Invoker","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JZO001%2FForge.Invoker/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JZO001%2FForge.Invoker/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JZO001%2FForge.Invoker/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/JZO001","download_url":"https://codeload.github.com/JZO001/Forge.Invoker/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240254181,"owners_count":19772386,"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":["csharp","delegate","delegates","event","exception-handling","subscribers"],"created_at":"2024-11-09T10:23:24.487Z","updated_at":"2026-06-11T20:31:29.846Z","avatar_url":"https://github.com/JZO001.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Forge.Invoker\nEvent delegate execution helper library\n\nHave you ever felt that, you got an exception, even if the issue is not on your side? \nTypical situation, when you are a library developer, raise an event, and one or more subscribers throw an exception. The issue get back to you, you should handle it. Thanks...\n\nOne more problem with this: if I have five subscribers on my event, and the third one throws an exception, the last two subscriber's event handlers will not run, because of the issue. That is not expected behaviour.\n\nWhat is the solution? Add a protected stack, a try/catch block around the subscribers, catch the exception, write a log entry, than continue to send the event\nto the others.\n\nThis is a very small and generic library to achieve that.\n\n\n## Installing\n\nTo install the package add the following line to you csproj file replacing x.x.x with the latest version number:\n\n```\n\u003cPackageReference Include=\"Forge.Invoker\" Version=\"x.x.x\" /\u003e\n```\n\nYou can also install via the .NET CLI with the following command:\n\n```\ndotnet add package Forge.Invoker\n```\n\nIf you're using Visual Studio you can also install via the built in NuGet package manager.\n\n## Usage / Example\n\nIn the following example, we have five subscribers on an event. In the middle, there is a subscriber, which simulates an issue,\nand throws an exception. The Invoker library handle this properly, protect the event sender and allow the last two subscribers\nto get the event also.\n\n```c#\nusing Forge.Invoker;\n\nnamespace InvokerExample\n{\n    internal class Program\n    {\n        static void Main(string[] args)\n        {\n            EventOwner owner = new EventOwner();\n\n            Apple subscriber1 = new Apple(owner);\n            Apple subscriber2 = new Apple(owner);\n            Worm subscriber3 = new Worm(owner);\n            Apple subscriber4 = new Apple(owner);\n            Apple subscriber5 = new Apple(owner);\n\n            owner.RaiseEvent();\n            Console.ReadKey();\n        }\n    }\n\n    class EventOwner\n    {\n        public event EventHandler\u003cEventArgs\u003e OnEvent;\n\n        public void RaiseEvent()\n        {\n            // The event, and the parameters (object? sender, EventArgs e)\n            Executor.Invoke(OnEvent, this, EventArgs.Empty);\n        }\n    }\n\n    internal abstract class Base\n    {\n        private static int _counter = 0;\n\n        private readonly int _instanceCounter = 0;\n        private readonly EventOwner _eventOwner;\n\n        public Base(EventOwner eventOwner)\n        {\n            if (eventOwner == null) throw new ArgumentNullException(nameof(eventOwner));\n            _eventOwner = eventOwner;\n            _instanceCounter = _counter++;\n            eventOwner.OnEvent += OnEventHandler;\n        }\n\n        protected virtual void OnEventHandler(object? sender, EventArgs e)\n        {\n            Console.WriteLine($\"OnEventHandler, instance: {_instanceCounter}\");\n        }\n    }\n\n    internal class Apple : Base\n    {\n        public Apple(EventOwner eventOwner) : base(eventOwner)\n        {\n        }\n    }\n\n    internal class Worm : Base\n    {\n        public Worm(EventOwner eventOwner) : base(eventOwner)\n        {\n        }\n\n        protected override void OnEventHandler(object? sender, EventArgs e)\n        {\n            throw new Exception(\"Simulating, something went wrong\");\n        }\n    }\n\n}\n```\n\nThe output on the console will be:\n\n```\nOnEventHandler, instance: 0\nOnEventHandler, instance: 1\nOnEventHandler, instance: 3\nOnEventHandler, instance: 4\n```\n\nThe third subscriber is missing from the output logging, because it has failed. The others are fine.\n\nThe Executor.Invoke method also can receive an ILogger in that case of an exception, and log the details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjzo001%2Fforge.invoker","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjzo001%2Fforge.invoker","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjzo001%2Fforge.invoker/lists"}