Cleaner C# code with "smart" using statements



Check out my Dependency Injection course: https://nickchapsas.com/p/from-zero-to-hero-dependency-injection-in-net Use …

28 Comments

  1. Is there any nice way to avoid writing try catch block on every method and still catch the exception message(Local exception message not the global exception message)?

  2. Yeah but this kind of profiler has a scope. Imagine if you want to measure your first call "var weather = await …" and then use var weather after the measuring ends. In such case you have to declare var weather before "using" statement. And depending on part of code you want to profile it can be many more vars which you have to declare previously. So the code still may be pretty clunky.

  3. Using the block version, with parenthesis, there is no need for "var _ = ", and using (_logger.TimeOperation(…) {} is perfectly fine.

  4. I recently used a similar approach. But instead of ILogger etc, I pass an Action to the constructor, which is then called when this "handle" leaves the scope. Basically using C# language constructs to mimic C++ RAII.

  5. That's really cool! I never knew `using` worked that way. Love how you deep dived into it and actually showed what happens under the hood.

  6. IDisposable + using brings to the table the equivalent of C++ destructors. In other words, you get the ability to guarantee that a block of code will automatically get executed when a variable falls out of scope, without having to clutter the code with more elaborate bootstrapping that distracts from the responsibility of the unit of code that you're writing. And while this is an incredibly powerful tool to have around, it comes with the caveat that in both cases, these mechanisms were designed with the intent to prevent human error regarding freeing up resources acquired by the object in question. You're not supposed to be doing anything other than releasing resources in this automatically executed code.

    That being said, this design intent is something I tend to abandon very quickly in all my projects. Rather than limiting IDisposable implementations to classes that free resources, I instead consider IDisposable implementations as classes that delegate code execution on object disposal by design because this is the feature that the language actually provides. I can use this in principle to free acquired resources, but also to run an arbitrary unit of code that might be interesting to have.

    Is this a problem for me? No, because I always check for IDisposable implementations. It doesn't matter how IDisposable is implemented in any given class because the intent is always the same: when the object is no longer necessary, it should be disposed. How this disposal manifests itself should not be a concern of the code that uses the disposable object in the first place. As such, it doesn't matter if Dispose actually releases resources because I would still look to ensure it gets called in client code.

  7. For anything that uses IDisposable in my experience think of anything that you would think is possibly relying up something other than itself for operations (something that could be understood as technically being left "open"). Reading and writing files makes sense because it requires interacting with the file and file writing system to complete its job. Networking operations makes sense because it requires interaction with http related mechanisms (input/output ports, channels, etc). So with that said suppose you were interacting with the registry using the RegistryKey class. Based on that line of reasoning would it most likely use IDisposable? The answer is yes. Doing what you are wanting to do (like writing to a file) is different than getting TO that point of being able to. That getting to that point of being able to and then closing/resolving that process is where IDisposable comes into play. You wrote to the file/you made the call, but that process that got you there needs to be resolved/closed.

  8. Hey guys, I would say this is not a good practice for such a scenario, here are the alternatives:
    1.use AOP if you want to log the time consuming for the api with correlation id
    2. if you want to control the scope, please try to use high order funtion to encapsulate the logic in this presentation, then warp your logic into lambda expression and pass into it

  9. Mh, so you are basically lying to the next guy by misimplementing IDisposable so you can save some indentation. Smart indeed.

  10. Hi Nick! Thanks for the video. It is very helpful.

    Since you are a Rider user, Could you please provide a video for us and explain the cool features of Rider + Extensions or configuration etc that you use?

    Thanks!

  11. Don’t interpolate messages for loggers. they are usually cached, interpolation would degrade performance, and remove ability to properly sort messages. Just add ms to args array.

Leave a Reply

© 2023 53GB