The best Nuget package you’ve never heard of
Вставка
- Опубліковано 4 тра 2022
- Use code FULLTIME for 20% off (first 200 people): dometrain.com
Become a Patreon and get source code access: / nickchapsas
Hello everybody I'm Nick and in this video I will introduce you to a Nuget which is used in tons of places and has more than 350 MILLION downloads but you don't know about. It has some really practical usecases and we will take a look at them in this video.
Give Castle.Core a star on Github: github.com/castleproject/Core
Don't forget to comment, like and subscribe :)
Social Media:
Follow me on GitHub: bit.ly/ChapsasGitHub
Follow me on Twitter: bit.ly/ChapsasTwitter
Connect on LinkedIn: bit.ly/ChapsasLinkedIn
Keep coding merch: keepcoding.shop
#csharp #dotnet #nuget
Congratulations on becoming full time content creator. You deserve the best.
"Full time content creator". Too bad for hungry companies, too good for us developers :D. Thanks!
Love this series, it's like unboxing videos for coding
Be careful, boxing and unboxing has a cost.
Congratulations Nick. It is well deserved, your expertise is the best.
Thank you for the introduction, i will definitely be using this in the near future
Also if you're testing, there's "Autofac.Extras.DynamicProxy" - which easily allows you to intercept anything, and then basically set up things, or detect things that you wouldn't detect otherwise. For example, for my APIs I have an interceptor "Exceptions must be documented" - the interceptor will make sure that if an exception leaves a controller, that controller has a swagger attribute of `[ProducesResponseType(typeof(InvalidDataException), 401)]` so that API consumers know what to expect
Great video Nick, congratulations on the channel milestone
Congratulation Nick. You deserve it, your content is some of the best detailed guides that you can find on the internet. On wards and upwards my friend :) lets get to 150k by end of year.
congrats! and yes, I never heard of this nuget although I use Moq on daily basis so thanks a lot for bringing this up.
Congrats Nick! Thank you for all the amazing knowledge!
I hope nuget packages like this are not bait for beginners so they make their codebase way to complicated. Add a few of these 'cool magic packages' together in the wrong hands and you have the maintenance nightmare of the future... A good enough design that is as simple as possible beats overengineering anytime. For me that means only use the minimum amount of packages, and only if it has a clear responsibility so it can be swapped out if that project dies or something...
You can say that about anything in programming as is not specific to this library. This was created because it solves a use case.
@@julealgon A lot of factors go in to this, project requirements, skill level, product lifetime. I agree on dont't reinvent the square wheel. Packages can hide complexity, you don't see it but it's still there. In my experience this hidden complexity is a major source of bugs and obstacles. A custom solution can have more visible lines of code, but a lower total complexity. No need to read poor documentation, hope for Google to point to solutions to problemens, you can just fix it, more freedom, and yes; more responsibility.
Amazing. I love your content and glad we will get more!
Nice tricks, Nick. And congrats for becoming full time content creator, can't wait for another useful tutorial :)
Congrats !! And thank you for the video !
Congratulations man! Love your content!
Congrats Nick. Your videos have always been high quality, a great learning tool, and a go-to reference. Between you, Tim Cory, and James Montemagno, I think you guys have C# covered.
Gratz Nick, your content is amazing. Keep doing it :)
I have used this library for creating a RPC type of communication in production. It's a great tool
Congratulations!:) And an idea about one of next videos: Your Blazor up-to-date impressons :)
Well done Nick! You are an inspiration!! 👍🏽
Congrats Nick!
This is awesome, I've been looking for something like this for a while now. Someone needs to make a modern version of the PolicyInjection library from years ago!
So happy for u. U make amazing content
The performance pit in this scenario wouldn't be the call to the intercepted methods, but the building of the proxy... there is where all the "reflection magic" occurs .. in a containerized application wouldn't be that important since you only do this once at app startup, but it can be a big hit in performance for serverless functions for example, where every time your function does a cold start, all the reflection is done again... but yet, Castle.Core is a great library for some things if used carefully.
Nice, bought one course dependency I. Thanks a lot
Congratulations mate, well done, love your work 😁😎. (Damn, I was hoping to hire you 😡)
Great video! Very informative! Will you be doing a video on asyncInterceptor by any chance? As far as I know, the asyncInterceptor package is not developed by castle team, and I'm quite worried about the performance.
Congratulations Nick
Glad you have been successful nick!
Great tutorial - had no idea AOP was this easy. Thanks for covering "But, Nick. Performance." How about "But, Nick. AOT compilation scenarios (no System.Reflection.Emit)."?
wow, I have researched about this lib before, but don't know how to use it. Thanks a lot
Since nobody else will do it I'll tip my hat at the suggestive thumbnail you absolute chad.
Nice Nick!
That could answer my old S.O. question ! I wanted to decorate all Serilog logging methods (from static Log class). But ended up manually replicate all their alternate signature same method. It displeased me so I end up using my own custom sinks that do my extra decoration logic each time it log something. I get warned on S.O. it is not the purpose of a sink. So yeah finally maybe it could be a more elegant solution.
This is exactly what I planned to do with a MiniProfiler.
Scrutor is a very underrated API; it's awesome.
Hi Nick! The interceptor performance is great, but what happens if u have to get the method name? Does it get way slower?
Nop because you already have it. It’s a pre-computed property
Very nice video. I was using this for logging and caching. Can you please make another video on async and await call on intercepting with castle proxy. For example by using asyncinterceptor. Also how do we manage the stacktrace on exception.
Amazing, I’ve been curious for how mocking framework works.
Congrats on being able to do content creation and education full time. You're great at it!
Re: Type-based decoration in C# doesn't scale...
If you need to move away from SRP, then yes, you're going to have a lot of methods/properties to implement on each decorating type and maybe a class hierarchy might be a better option. But I try to avoid reaching for Castle or any other reflection based interception approach because it's so easy for the code to become really difficult to debug and understand. I haven't run into any situations in the projects I work on (other folks use-cases could be completely different) where I need AOP via Castle and Type-based decoration doesn't work.
That said, the Castle project is really important to the .NET ecosystem and I use it every day (just not directly) for things like mocks in unit tests...
Thanks! I don’t agree with said statement though. If separated correctly and with the right mechanism (attributes) it can scale really nicely.
@@nickchapsas I was saying that in my experience, Type-based decoration scales just fine because you mentioned that it doesn't scale. The situations where Type-based decoration might not scale are when a type isn't adhering to Single Responsibility Principle (SRP). If it does, it will only have 1 or 2 methods (usually 1 in my experience), which is very very easy to decorate and looks like the "Intercept()" method you show with Castle.
The situations where I see AOP via reflection go wrong is where developers try to put context in attributes with string patterns. Attributes are very poor at this. Instead the intercepted method's parameters and return types are so much easier to work with when doing Type-based decoration.
If you are intercepting 1 method on a type with a huge public surface area (lots of methods/properties) then AOP via reflection is your best option, but this seems more suited to types you can't control. If you can control the types, try to follow SRP and then Type-based decoration is very easy to implement and maintain.
@@seangwright
Introduce to you the AOP library that none of reflection and simple with only two parameter-less attributes.
nuget package InterfaceFillerCodeGen
AOP, castle is a port from java. I think that have more the 20 years old the interceptor
I'm a little bit ashamed of myself that I haven't heard about this NuGet. This is pretty cool stuff.
Imho these kind of videos are so important. A lot of new C# devs have no idea of all the possibilities, just because they have no idea about NuGet.
Do you know how well does Interceptor works with Async methods? And what if you want to make async calls before intercepted async method?
In a full decorator implementation, you'd just create a DecoratorBase with all the methods set virtual and calling the decorated instance by default, and then in concrete decorators you'd only override the methods you need to override :)
Interceptors can still be massively useful in various cases, it is just that decorator is solvable in a nice manner without them %)
I find inheritance based decoration a very bad practice and very cluncky to work with
@@nickchapsas idk, has been working alright for me. Might be a matter of taste...
Also, it is not exactly inheritance-based, you do not extend the class to decorate it. You extend the DecoratorBase to build a decorator that works with any instance implementing the same interface as DecoratorBase... It is essentially the same thing you cover in the beginning of the video, but easier to add/delete/modify methods :)
@@dnl_blkv The difference is coupling. By basing it on the interface and then letting the IoC container do all the work, there is 0 coupling between classes that shouldn't know about each other.
@@nickchapsas I don't think I see how an approach with DecoratorBase adds any uneeded coupling to be honest.
So you suggested this as an alternative yo using Dynamic Proxies:
1. IThing
2. ThingSomethingDecorator : IThing
I suggest:
1. IThing
2. ThingDecoratorBase : IThing
3. ThingSomethingDecorator : ThingDecoratorBase
(Not comparing the classic decorator to dynamic proxies here, only comparing the classic decorator to interface-only decorator, and still struggling to see how the interface-only version has lower coupling or is otherwise better in any sense :))
@@dnl_blkv Do you have repo for example? So I can point out the coupling.
This channel is the best Ad for Ride IDE you could ever ask for. How cool would it be for you to be sponsored by JetBrains?
Thanks
The title and thumbnail makes this video look rather saucy.
Somehow when I saw the thumbnail my mind went to Castle. Such an awesome package.
It’s one of those things that you might have heard of but never actually used yourself. At least it was for me
@@nickchapsas I think I started using it when I needed duck-typed composites to avoid statically defined `IFooAndBar : IFoo, IBar {}` scenarios. Overall I made things about 30% slower which was very much worth it in the context (small numbers)
Hmm, don't know if that thumbnail was supposed to be suggestive but I came here for the nuget packages nothing else!
9:10 the interceptor should probably have been added as a singleton as well, no need to create it every time.
Hi, Thanks, very useful!
How can I add DI extender, that contains AddInterceptedSingleton?
using the Castle.Core can you have multiple decorators on the same interface? on your example the IWeatherForecast?
You can yeah. The methods accept an array of interceptors so you can have as many as you want
@@nickchapsas IMHO it is not as good as it seems, it causes magic which causes pain, had seen 2 projects that became hard to support due to usage of this stuff
Really great library. Although you should mention that for async methods this won't actually work. You have to add a continuation and log after task is completed/failed/cancelled.
There is an async interceptors package that supports that
@@nickchapsas awesome! thanks
Nick, did you stop working at checkout? Do you think it will affect your prefessional development?
I did yeah. I don’t think it will, no. I’ve been through the whole stack for years and for the past year I didn’t write any code because I was a people manager. The content isn’t really driven from work anymore but my personal learnings
great upload, like always
can you make a video on how to make an API with Entity Framework for absolute beginners, Im having trouble finding a guide on this for newbies, thank you!
I would love to hear your opinion on this vs AOP programming. I unfortunately learn most of my .net core from you since I am still on the legacy version.
I was a great fan of AOP magic up until to the point where debugging production crash dump started becomming nightmare.
I think we can do it with Fody Addins as well, instead of castle core intercept. thank you anyway
use it! like we say in Peru : "give quality of life to yourself" XD
what about async? I suppose interceptor will track time only until ContinueWith.
There is an async interceptors package
Boom bought miminal API!
What is the security risk using 3rd party packages that are dependent on other 3rd party packages? Can someone update a dependent package without changing the version of the package it depends on?
The security risk is huge especially in the Linux world.
Generically if you're worried about this kind of stuff and are of any size you will have a local npm to cache, and you will have md5 hashing checks for Library validation, and at larger sizes even have a group that does security validation of open source libraries being used, honestly the biggest safety valve is generally just not upgrading off of a "known" safe version which is how we often end up with such stale tech stacks. There have been widespread vulnerabilities discovered and it's just something you deal with, you can't be expected to make modern software efficiently without building on libraries.
At least the "logging" example you can easily active with request filters no packages are needed.
But that’s request logging. How do you narrow it down to specific services?
Nick, I tried this using your example code, but I cannot seem to find the IServiceCollection method "AddInterceptedSingleton". I initially tried Castle.Core v5, then tried the same version as yours (4.4.1), but the method wouldn't resolve. My project is a .NET 6 console app. Can you help?
That's a method I wrote myself, it's not part of Castle
@@nickchapsas Ah yes, thanks. I had watched this video a few weeks ago, and then was following along step-by-step last night. I paused it when I couldn't find the method, and forgot you'd written it! Excellent video BTW.
oh my, this is gold. I have "legacy" code which inlines everything, so I've used scrutor/decorator to move out the cross cutting concerns. And this... is next level. I allows to do the same as decorators, but with a much quicker dev time. Love it. Thank you Nick.
System.Reflection.DispatchProxy does something remarkably similar. That's what I use for interceptor proxies.
I love how he says, "Let's go straight into the video" and then doesn't.
What about interception of async methods?
There is a separate AsyncInterceptors package from castle that has a sync interceptors
Make a video why you use rider instead of visual studio please
Could you also make a video for async version?
You can use the async interceptors package
@@nickchapsas that’s the info I was looking for the entire video !! 😅 I’ll look into it !! Thanks
Does SimpleInjector do this ? As efficiently ?
SimpleInjector is an ioc framework. It’s a different thing all together
@@nickchapsas It has a extension for it InterceptionExtensions -- but for my ignorance the surprise is that Castle is NOT. I googled it, only Windsor -- OK
THANKS!!!! (aand sorry for the time waist)
Awesome. LIke.
Anybody used IAsyncInterceptor with Polly for handling exceptions or throttling?
I would have known nuget cost-free package that helps for injecion services to the class and then I wouldn't have to create constructor with optional NullArgumentException.
Please share code for this example
"Why aspect-oriented programming in C# is pointless" 👀
This isn’t aspect originated programming. It’s like saying that a middleware or a filter in ASP.NET Core is AOP. It goes way beyond interception
Do it with less phrases decorator pattern
Why not talking about postsharp ? It does AOP without polluting your code with proxies.
Because I don’t like AOP or postsharp. And no, just method interception, isn’t AOP
Please can you do a full tutorial with Blazor?
Including EFCore (Relationships), Database Integration, Login/Registration and Authentication including Auth Roles etc.
I don't care if it's like a 10-hour tutorial. :)
Yes I second that, that would be awesome. 20-hour is also good.
Interesting! Java has dynamic proxies out of the box, and Retrofit, a popular library for creating type-safe API clients, is implemented with dynamic proxy.
Castle.Core is a great package (I'm using it in conjunction with Castle.Core.AsyncInterceptor), I would also suggest you take a look at the AspectCore package, it has 1.5k stars and I found it very easy to use for achieving AOP features as you point in your video, the only downside (and a deal-breaker for me) is that it is not working with Scrutor Decorate method.
For simple measure time, Why not just make your own middleware?
Because middleware is endpoint wide and it measures things across the full request. what if you wanna measure a specific method? What if you wanna measure how long you take to process a message? This generic approach is way more flexible
How about giving Blazorise a chance?
I don't do Blazor so I don't think this would happen
Does not work for async methods... proceed returns inmediately :(
There is an async version of the package
Are you quiting checkout?
I am yeah
@@nickchapsas Aw man that's a big change! Best of luck
I've been coding for like a year now. How do I bridge the gap--how do I understand what is going on in these videos?! lol
Just keep coding, trying new things, pushing your limits. The gap will be bridged via time, shortcuts will cripple your mindset.
Title in thumbnail should be used as a pickup line. Expected conversion rate?
What's funny is it honestly didn't cross my mind that it would be suggestive 😂
@@nickchapsas Probably says more about me than you. :)
Btw, I think you really nailed the scope and length of your videos. 10-15 minutes are perfect. (Just talking about videos haha)
The face he makes in the thumbnail definitely sells it.
Tip: name the NuGet package up front and not well into the video.
It’s in the description. There is no point throwing a package name of you don’t understand what it is and why it exists
make timestamps for your videos
Please next time at least loosely connect title with what package is doing :S
That’s not how titles work
@@nickchapsas Idk, felt clickbaity to me, but im not content creator, nor my english is the best so nvm.
Anyways GZ on huge milestone. Looking forward for new C# content ^^
Plz, let this be your last click bait...
It won't and here is the thing. People don't understand how clickable titles work. If the title was "How to use Castle.Core to create interceptors" or "Creating Dynamic Proxies in C#" then best case scenario 1/10 people would actually watch the video for the simple reason that you need to know what those things are before you watch the video. What is Castle? What is Castle.Core? What is a dynamic proxy? What is an interceptor? People don't know what they don't know and these titles make for honest titles but not clickable titles. Ultimately the goal is to get people to click and watch the video. Real clickbait is shut down by UA-cam very quickly. The fact that the video gets views, positive comments and likes means that people watch it. That's the definition of legitbait. So no, my titles will keep following the format that I think is appropriate in order to get as many people to learn as possible. If that's not your cup of tea you can unsubscribe and mute the channel.
This video setup is weird.. did developers need clickbait and surprise lessons on random packages?
I think it would be more useful if you could search for it by topic when you needed to find it?
They did actually. Something is clickbait when the video content doesn't deliver to the perceived promise of the title. As you can see by the comments and the performance of the video, most people didn't know about this. True clickbait videos get buried into the groud by YT's algorithm so if a video does well, it wasn't clikbait. It was just clickable. You assume that "How to create dynamic proxies in C#" would be a better name, but unfortunately, you are wrong. Such a title assumes that the person reading it, knows what a dynamic proxy is in the first place, rendering it useless because if you know what they are, then most likely you know how to implement them. So, yes, for UA-cam educational content, such titles are just needed, they are a must.
Bloated architecture
Love this! Very elegant. It appears CreateInterfaceProxyWithTarget() takes params[] IInteceptor so you can pass an array of interceptors too.
Correct and the order matters. It effectively creates a pipeline
I was looking for c# counterpart of java.lang.reflect.Proxy and this looks to be exactly it! Thanks!
You should have told the package name in video title, this wasted a lot of time until i reached the word Castle.Core, i already know about!!
It’s in the description
invokation.Method.Name get the method name, is there a way to get the classname? The method names will overlap between classes. Thanks for the video!
Yeah there is a Type property in there
@@nickchapsas I was able to get the proxy interface of the class with new StackTrace().GetFrame(2).GetMethod().ReflectedType.Name, which is good enough to identify the class
Scrutor is fun but it makes order of calls in register types matter. This breaks the default behavior of container builder. Its a shame because the easy fix would be structuring the api differently. For example: services.AddTransientForDecoration().DecorateWith().DecorateWith()