Clean service decoration in .NET Core using Scrutor

  Рет қаралды 36,792

Nick Chapsas

Nick Chapsas

Күн бұрын

Пікірлер: 55
@khellang
@khellang 4 жыл бұрын
Nice 😎
@acousticbrothers1491
@acousticbrothers1491 4 жыл бұрын
Hello master, can I email you for a question, I really got stucked, I have a stackoverflow question, and I can send you the link, or I can post the link in here..
@nickchapsas
@nickchapsas 4 жыл бұрын
Ofc you can email me
@acousticbrothers1491
@acousticbrothers1491 4 жыл бұрын
@@nickchapsas Im sorry, I couldnt find your email...
@acousticbrothers1491
@acousticbrothers1491 4 жыл бұрын
@@nickchapsas oh, I found it from YC Slack, I m sending you email right now.
@KhalidMeftah2014
@KhalidMeftah2014 4 жыл бұрын
Thanks for the series you have created, they are very helpful. Are you planning to release Event sourcing course?
@nickchapsas
@nickchapsas 4 жыл бұрын
A full event sourcing course is not a priority currently but the topic and its applications is totally something I would like to cover.
@shreyasjejurkar1233
@shreyasjejurkar1233 4 жыл бұрын
Do our commands needs to go though the Cashed Repository like queries or directly into the repository to update the records!
@nickchapsas
@nickchapsas 4 жыл бұрын
The answer to that is that it depends, but once you add the decorator, you don't really have a choice. The cached one will be used always. You can ofc make it into the cached repository logic that when you are doing an action like "CreateCustomer" that it wouldn't use any cache and go to the database every time but again this comes down to your usecase.
@shreyasjejurkar1233
@shreyasjejurkar1233 4 жыл бұрын
@@nickchapsas so what I understand is that we need to call the main repository update code from the Cashed Repository directly.
@nickchapsas
@nickchapsas 4 жыл бұрын
@@shreyasjejurkar1233 Yeah but that is done automatically through the decoration logic of Scrutor. The IRepository within the CacheRespository will always be the main repository.
@shreyasjejurkar1233
@shreyasjejurkar1233 4 жыл бұрын
@@nickchapsas So what should be the code inside the Update method in CashedRepositoy from your point of view? Just a empty function?
@nickchapsas
@nickchapsas 4 жыл бұрын
@@shreyasjejurkar1233 If you don't need any custom logic then simply do "return await _repository.YourMethod();" and it will just bypass the cache layer.
@minhgiangho1410
@minhgiangho1410 4 жыл бұрын
But why we do not use pipelinebehavior of mediatr in this case?
@nickchapsas
@nickchapsas 4 жыл бұрын
Because this isn't specific to a specific action. It is an infrastructure layer thing, not a domain one, so it shouldn't be part of the pipeline. In fact, the pipeline shouldn't even be aware of it, which is exactly the cases here.
@minhgiangho1410
@minhgiangho1410 4 жыл бұрын
@@nickchapsas so, what should pipeline handle?
@nickchapsas
@nickchapsas 4 жыл бұрын
Just business logic behavior. Validation for example is business logic related. Caching is an infrastructure concern unless it's done for a business reason.
@ssubbuanil1
@ssubbuanil1 4 жыл бұрын
Great article Nick. Query: Once the data is stored in cache, if we need to update based on some condition or timeframe. What will be the best approach on this?
@nickchapsas
@nickchapsas 4 жыл бұрын
That would go in the CachedRepository class. You can have some time to live for your cache entries or even invalidate on demand.
@ricardoduarte442
@ricardoduarte442 2 жыл бұрын
Hi​@@nickchapsasHow would you approach the invalidate on demand?
@acousticbrothers1491
@acousticbrothers1491 4 жыл бұрын
Yeah!
@user-ue9zo3mo7w
@user-ue9zo3mo7w 4 жыл бұрын
Thank you man =)
@user-sl2sp8jy7b
@user-sl2sp8jy7b 6 ай бұрын
I still dont get it, why inheritance variant is worse than this magic approach
@berkarslan
@berkarslan Жыл бұрын
Too hacky. I would achieve the same thing by the following code without using that library... services.AddScoped(); services.AddScoped( provider => new CachedCustomerRepository(provider.GetService()) );
@dennycrane2938
@dennycrane2938 Жыл бұрын
I want to decorate an object of an unknown type so I can add inotifiypropertychanged (or similar) behavior, where the decorator would be able to track when properties were modified. Can scrutor help with that, is this only for DI? Maybe dynamicproxy would be more appropriate...
@sulmarpl
@sulmarpl Жыл бұрын
Thank you very much. This is what I was looking for.
@stridemann2338
@stridemann2338 Жыл бұрын
Well, actually this is not Decorator, but a Proxy pattern. Because Decorator never prevent calling wrapped object (just adds additional functionality). Proxy can do that and should, and it used for caching.
@propro8040
@propro8040 Жыл бұрын
Hi Nick Chapsas . Just one question can we use this approach (08:16) not only GetCustomerByID but also GetAllCustomers. So cache all Customers and use them if needed ?.
@oldwhitowl
@oldwhitowl 2 жыл бұрын
Hi Nick, I'm a bit late to this one and am maybe having a moment so forgive me, but wouldn't that configuration force you to use singletons for all your classes? I'm using CQRS and was looking at implementing caching at a application service level which would mean my service classes and the query/command classes they utilise would also have to be singletons (or maybe transient). Is this a good idea? Love the videos!! Thanks.
@ricardoduarte442
@ricardoduarte442 2 жыл бұрын
Hi Nick, how would you go about implementing an InvalidateContext in this case? I can see that this case would be simple to add for example an timed cached, but what if for example I want to force the method to get the item from db instead of the cache? Would I have to create some external method that would control this and inject it in the cached implementation? Or would you just add a property to the interface method and only implement it from the cached side? (I don't think that the 2nd option would be clean >P) Btw, I love your videos man!
@emerynoel567
@emerynoel567 2 жыл бұрын
Thanks Nick. I enjoy many of your videos, but Scrutor seems needlessly roundabout. I am 100% sure that decorating the DI like this is going to throw many devs for a loop. (Most) everyone understands how the DI works, but this seems to be subverting those expectations. You yourself had to say "now watch carefully". Instead of decorating, why not just have 2 interfaces, ICustomerRepo and ICachedCustomerRepo (which constructs with ICustomerRepo), and then inject whichever interface you want? It seems to me that would a) make the code clearer, and b) eliminate the need for yet another nuget dependency.
@lyrion0815
@lyrion0815 2 жыл бұрын
Imagine you already have some (many) classes or controllers which all use the ICustomerRepo... you would have to change all usages to the ICachedCustomerRepo to get the cached version injected. If you use the same interface, you dont have to change any of these classes, and they will all get the cached version injected without any additional work.
@emerynoel567
@emerynoel567 2 жыл бұрын
@@lyrion0815 that makes sense. But I would still consider making those many changes for clarity's sake. You can also simply swap out the implementation. ICustomerRepo becomes the cached version, and it now takes an ICustomerDBRepo, which is impl a melted by the old class.
@lyrion0815
@lyrion0815 2 жыл бұрын
@@emerynoel567 It feels natural to me, doing it like he shows. But I've also been doing it like this for many years (without scrutor since I didnt know that package).
@omarabulaban51
@omarabulaban51 2 жыл бұрын
Wow, just in time!!
@krishnaDhungana
@krishnaDhungana 3 жыл бұрын
Hi Nick. Great video. Can I use Scrutor for cases like sending email to customer after the order is completed in original service?
@dmytro.kryvoruchenko
@dmytro.kryvoruchenko 3 жыл бұрын
Hello, can we decorate twice (maybe more time the same class)? For example once for caching, and once for logging? is it possible?
@nickchapsas
@nickchapsas 3 жыл бұрын
You can decorate it multiple times and also define order on the decorators
@dmytro.kryvoruchenko
@dmytro.kryvoruchenko 3 жыл бұрын
@@nickchapsas Thank you!
@andreibicu5592
@andreibicu5592 2 жыл бұрын
If the order can be defined, can we decorate a decorator? With Dmytro's example, is it possible the CustomerRepoLogger to use the CachedCustomerRepo instead of CustomerRepo ? Can you please confirm this ? Thanks!
@clearlyunwell
@clearlyunwell 3 жыл бұрын
👍
@temp50
@temp50 3 жыл бұрын
I 'm not sure if it is worth to use it :/ It is confusing as hell and in a big project, new colleagues will just leave the company the day they have to deal with a code like this.
3 жыл бұрын
Too convoluted for my taste. I'd stick with my Customer class that has the efficient caching feature (reload on timeout and collection version). Adding caching feature over a Store class on mine would't really break the single responsibility principle (cache and store). Still you got my thumb up !
@user-np9nk9kt2t
@user-np9nk9kt2t 3 жыл бұрын
As a side note for any other confused developer - the example in this video is good, but that is not a structural Decorator pattern but a classic Chain of Responsibility behavioral pattern. Your _customersRepository is an example of _next handler in the chain of event handlers. We use decorators for some shenanigans in our code - to add some extra features, extend the type, but they are not allowed to break the flow, at least by the classic definition of Decorator.
@keenkidash7616
@keenkidash7616 3 жыл бұрын
I didn't know about Scrutor. I use to work with Autofac which already brings up services decoration on its own. Anyways, good to know about other interesting tools.
@hyperspaced77
@hyperspaced77 3 жыл бұрын
This example is just not good for sooo many reasons...
@nickchapsas
@nickchapsas 3 жыл бұрын
Do you mind sharing? I am interested in why it's a bad example so I can improve it in the future.
@hyperspaced77
@hyperspaced77 3 жыл бұрын
@@nickchapsas You are using DI "sourcery" to force a "pattern" to work. Without taking into account why you cache on the repository layer (instead of on the communication layer and thus using a middleware for this matter) you basically *want* to inherit from the concrete implementation of your repository. Injecting another instance of your base repo in the "derived" repo is simply cumbersome. You don't need yet another fancy nuget reference in your project.
@nickchapsas
@nickchapsas 3 жыл бұрын
You could cache on the repository layer. You could cache on the service layer, the app layer or any layer that you want. Different levels of caching represent different things. This is a feature that third party .NET DI frameworks have been supporting for years. You don't inherit from anything. You are implementing interfaces and use DI to resolve services where you want them to be resolved.There is no sorcery involved in this. Just good ol' simple code.
@Yarkendar
@Yarkendar 4 жыл бұрын
Awesome channel, thanks for videos
@ibrahimhussain3248
@ibrahimhussain3248 4 жыл бұрын
Is it possible to do this in a library without api?
@vamvdotnet
@vamvdotnet 4 жыл бұрын
Hi Nick! I'd like to make a suggestion about .Net Core Web API with Elastic Search training video. Thank you!
@rao6815
@rao6815 4 жыл бұрын
Hi, I am little bit confused please clarify me. When we create Singleton instances and then we decorate this with an other crashed layer and everything is now in our memory, will this process is much memory intensive? Do we need high memory?
@hannasamia6739
@hannasamia6739 4 жыл бұрын
Thank you Nick! Great tutorial I have one question : if I have multiple methods is my repository/service and in the cached version of it don't include all the methods, my request will first in the cached and won't find the function. what will happen next? will it automatically go to the no cached version ?
@krzysztofurban4561
@krzysztofurban4561 4 жыл бұрын
If your cached version inherits from interface, it should implement same method as the non cached repository.
Benchmarking C# code using BenchmarkDotNet
17:00
Nick Chapsas
Рет қаралды 58 М.
Creating a console-based microservice in .NET Core
13:26
Nick Chapsas
Рет қаралды 23 М.
He bought this so I can drive too🥹😭 #tiktok #elsarca
00:22
Elsa Arca
Рет қаралды 47 МЛН
Fake watermelon by Secret Vlog
00:16
Secret Vlog
Рет қаралды 14 МЛН
Dynamically enabling features with Feature Flags in .NET Core 3.1
11:45
Should you stop returning "null"? | Functional C#
11:32
Nick Chapsas
Рет қаралды 105 М.
Don't throw exceptions in C#. Do this instead
18:13
Nick Chapsas
Рет қаралды 258 М.
Elegant API Versioning in ASP.NET Core (Web API)
21:27
Nick Chapsas
Рет қаралды 95 М.
Mapster, the best .NET mapper that you are (probably) not using
24:02
20 Nuget packages that every .NET developer should be familiar with
15:33
Making async code run faster in C#
10:28
Nick Chapsas
Рет қаралды 106 М.
How to add clean Retrying in .NET Core using Polly
15:30
Nick Chapsas
Рет қаралды 62 М.
He bought this so I can drive too🥹😭 #tiktok #elsarca
00:22
Elsa Arca
Рет қаралды 47 МЛН