0

In a C# class library project, it is possible to globally subscribe to an event? For e.g. say the project contains 10 classes. If I had to subscribe to AppDomain.UnhandledException event, I can have this line of code inside every class

AppDomain.CurrentDomain.UnhandledException += MyExceptionHandler;

Is there a way to declare this so that the code doesn't need to be repeated inside one dll?

reggaemahn
  • 6,272
  • 6
  • 34
  • 59
  • Do you mean automatically subscribe every class in an assembly to an event where each class doesn't derive from the same base class? Probably Reflection – James Jan 06 '16 at 15:08
  • 2
    Just FYI, if you put this line of code in every class, you'll be registering for the event once for every instance of any of those 10 classes, and when the event fires it'll be "handled" that many times--probably not what you want. – adv12 Jan 06 '16 at 15:08
  • @JamesBarrass Hi. Yes, exactly. – reggaemahn Jan 06 '16 at 15:10
  • @adv12 Yes, I didn't quite think of that. What would you do in that case? If the classes are not all static that is. – reggaemahn Jan 06 '16 at 15:12
  • I would strongly suggest you only register for this event once for the entire application. You could put the registration in the `Main` method of the "Program" class that Visual Studio creates for you, and you could add the event handler to that class as well. – adv12 Jan 06 '16 at 15:15
  • @JeevanJose You could put the code into the static constructor of each class, which would fix `adv12`'s concern. However, can you clarify what you are trying to achieve here, as there may be a better way... :) The only way I can think of to avoid duplication would be to use [AOP](https://en.wikipedia.org/wiki/Aspect-oriented_programming) techniques, but it's hard to understand why you might want to do this... – RB. Jan 06 '16 at 15:15
  • @adv12 It's a class library so I don't have the `main` method. I want to subscribe to the event from within the class library. – reggaemahn Jan 06 '16 at 15:17
  • The right place would be in `Program.Main` method, but a library doesn't have one. You should create a static method, used by all the other classes, that manages the event so it's only added once. – Matthew Jan 06 '16 at 15:18
  • @RB. Simply trying to catch certain types of Exceptions in a global exception handler. – reggaemahn Jan 06 '16 at 15:18
  • 1
    @RB., putting it into the static constructors of 10 classes would still cause 10 handlers to get called, and besides it doesn't make sense to have application-level logic (what to do when an unhandled exception is thrown) in random classes that are not themselves application-level classes. – adv12 Jan 06 '16 at 15:18
  • @adv12 I totally agree, and that is what I was trying to gently push the OP towards by asking what his motivation was :) However, he seems comfortable with 10 handlers being called (and will have to be to achieve what he claims to want to achieve). – RB. Jan 06 '16 at 15:24

1 Answers1

2

Assuming the exception handler is common to all classes and instances created from those classes (aka MyExceptionHandler can be a static method in a helper class), you could then try to resort to module initializers which would allow you to run code upon assembly loading.

See this answer for more details. In particular, one of the comments on the answer will provide you with a simpler way (Fody/ModuleInit) to take advantage of this feature that is available since CLR 2.0, but not exposed in C#.

Having said that, this seems like a very uncommon requirement as usually the party that has an interest on being notified about unhandled exceptions is the application itself and not the libraries that the application loads.

Community
  • 1
  • 1
João Angelo
  • 56,552
  • 12
  • 145
  • 147
  • Was about to post an answer about `Fody/ModuleInit` when you updated your answer. – Scott Chamberlain Jan 06 '16 at 15:24
  • I personally never used it, but it does seem to be of interest to a situation like this. Although, I must confess, I'm a bit curious about the motivations behind the described scenario. I'm used to only subscribe to that event at the application level. – João Angelo Jan 06 '16 at 15:32
  • I never knew about module initializers. It seems complicated but the Fody/ModuleInit project looks interesting. The motivation behind this is a domain specific third party api that has a known bug in a specific version that I have to use. There are multiple classes that can cause (mostly) expected errors which I can write workarounds for. – reggaemahn Jan 06 '16 at 15:38
  • Ah, workarounds for third-party issues, that usually warrants some creative solutions. – João Angelo Jan 06 '16 at 16:03