Just came to say that your OpenTelemetry course is actually sick. Just finished it. Good job!
@diegofaria81872 күн бұрын
Thank you for the video. I'm studying it to implement it in my work. It'll be the best way to solve our problem.
@TerkelBrix4 күн бұрын
Thank you for sharing your thoughts. I find them exciting. My thoughts went to Whitehat Hackers. One could argue they operate under a shared codex /code of conduct. Thank you for making great content. 🎉
@aerisseon4 күн бұрын
Do we need a well defined code of conduct specific for this industry? Being a decent person, doing the right thing, not using your technical skills to cause harm and damage to others should be enough. There are lots of professions, general code of conduct applies to all. I feel that All the points you mentioned applies and are being practiced, and it actually forces us to comply, otherwise we can lose our job and we lose credibility...
@Fikusiklol5 күн бұрын
Hello. How come not having a repo here doesnt break encapsulation? How come having "too many" get methods breaks SRP? We are just working with database and then entire DbContext is a big SRP breaker. Interfaces also a thing. There are things called Read/Write models and CQRS for a reason. Repos for writes belong to domain layer, cause those "too many" get methods should come from a business. TLDR: you unit test repo if it has any mapping logic, you can integration test it independently if you want.
5 күн бұрын
Key points At the time when commertial open source was driven by Java developers and unit testing was a cool new wave, Microsot thought that unit testing can be sold for professionals. So MSTest was available for VS Professional subscribers, but not for Cmmunity Edition version. A funny fact: MSTest still has [Author] attribute. The person to blaim when test fails.
@g.brantzos5 күн бұрын
Uncle Bob in one of his presentation said that "We are an unregulated industry, but it's only a matter of time or luck, that a HUGE incident will happen, with human casualties and then politicians will come and regulate us". I believe that this is very close to what you mention in your video. We need to protect our industry by getting self-regulated (really close to a Code of Conduct, as you mention). If someone else does this for us, it won't be fun...
@aerisseon5 күн бұрын
Many programmers work for companies, and by (to me) I take it as we are regulated by the policy of our employer/enterprise. Especially in IT companies, We even have our regular compliance test/review including IT/tech/security related concerns.
@MarkRendle7 күн бұрын
Yay! See you in Porto!
@gui.ferreira6 күн бұрын
See you there 🫡
@rmcgraw794310 күн бұрын
I would it if you could make a video that shows how to return an interface that is a value type from a struct that implements that interface. It’s possible, but I only know one way of doing it; perhaps you know a better way.
@rmcgraw794310 күн бұрын
Ouch! That last bit can bite you. Man,that’s not right. They need to fix that.
@rmcgraw794310 күн бұрын
I’ve used this long before it was ever given a name, and while most know it as Hex Arch, I call it XPlicit Arch, since architect is supposed to be about interfaces and contracts, not implementations. For you C guys out there, when he speaks of Ports, think Interface or abstract class, and adapters can be 2 things (either an interface implementing class or abstract class that implements that interface but serves as a translator). There is some cost to this architecture, as it’s not easy for junior or mid level coders to fathom at first, but it pays off for enterprise solutions. It’s Dependency Injection intensive, so it makes people code to interfaces, another plus. Also, it doesn’t have to be followed exactly, and you can use it as your enterprise core architecture, which it is ideal for, but it can also be applied in an complex application as well. For instance, a web portal might have it’s own entire hexagon that interacts with the “Core” enterprise hexagon. The main thing to realize is that nothing deals with concrete instances except the deepest regions in the Core of each hexagon. Everything is talking to each other via interfaces, allowing for future change and flexibility. Search “The Software Architecture Chronicles” by Herbert Graca for a thorough explanation on this architecture.
@gui.ferreira6 күн бұрын
Thanks for sharing. I agree with you that it can be harder for a Junior, but I think it's easier to get it than other styles. Those articles by Herberto are amazing.
@Aweklin12 күн бұрын
Thanks for the clarification. But why do people not include oData in this kind of comparison? Is it only used with .NET?
@antonmartyniuk12 күн бұрын
I am using REST, gRPC and GraphQL in my projects. - gRPC for synchronous communication between microservices. or for client-server communication when a server can call methods from client - GraphQL HotChocolate for frontend-backene communication. I can't imagine my life without GraphQL, it's so much easier with it. And much more productive. You can combine multiple queries on the frontend and get what you need efficiently. When you need to show table view data on the frontend with filtering, sorting and paging support - HotChocolate has these all built-in that automatically integrates with EF Core. - for the frontend we also use code generation to generate all the types from the GraphQL schema, it significantly makes us more productive.
@JoaoVictorFerreira-xx1rq12 күн бұрын
Once I used Graphql with strawberry library to consume an array of large objects and the performance was horrible, multiple times slower than rest. With my small knowledge/experience with Graphql, I imagine it is better than rest only for BFF and small requests as you said.
@gui.ferreira6 күн бұрын
That's the problem. It's hard to get it right
@hridzumbb13 күн бұрын
but rider isnt free...
@gui.ferreira13 күн бұрын
I don't say it's free. I say that I'm using it and love it.
@psycho.2u15 күн бұрын
Great video that explained it very well. But I feel like everything can be simply created using Mocking libraries For example, a mock might be heavier than dummy, but serves the purpose Mock might be heavier than stub, but we can still configure it to return the expected result. If you think that there is complexity in setting up and doing duplication, we can do the following Assume, we use xUnit. In that all mocks should be private fields. And we introduce private methods where we setup all mocks as expected. For example, we want to run a test where a stub should return false. Simply add a private method that says SetupServiceAToReturnFalse(), and continue the test. We can add similar to true as well In arrange section, call all setup methods for the mocks and continue the test. Also, we can configure every mock with general values in constructor which can be overridden in mock's setup private methods. So, we make test method even simple by only overriding the default mocks I appreciate so much details added in this video. It is necessary to understand all the concepts to know how we can do without library. But mocking libraries such as Moq really simplified it all. Please let me know if something may go wrong with the above setup on any scenario
@gui.ferreira14 күн бұрын
mocks are a Swiss army knife. They do it all. However, I'm a huge believer in the expressiveness of simplicity. Often, avoiding the mocking abstractions creates tests easier to maintain. So, my point is that Mocks need a bit more mastery to do it right
@jflaga15 күн бұрын
Hi, may I know what IDE you are using in your video? Thanks.
@gui.ferreira14 күн бұрын
Hey! I have a video on it. kzbin.info/www/bejne/rYKqkH-kqch0h7Msi=uy3fc9o0Zsxb2VGK
@psycho.2u15 күн бұрын
Awesome. Thanks for the video
@gui.ferreira14 күн бұрын
Thanks for watching!
@Z-K30017 күн бұрын
ّ
@dandoescode17 күн бұрын
These properties seem to be missing from the new API. How do you configure them? logging.IncludeScopes = true; logging.IncludeFormattedMessage = true;
@gui.ferreira14 күн бұрын
There's an overload that gives you access to that. 😉
@dandoescode14 күн бұрын
@@gui.ferreira thanks! 😄
@padnom499118 күн бұрын
Thx again for your video. I have difficulty understanding. Because if I have a GenreService class with a lot of business logic that calls this repository. If I remove GenreRepository, I will then have to inject the DbContext directly into my service class. As a result, regarding unit tests, I will no longer be able to use a fake repository? Furthermore, can we have repositories in some cases and not in others? How does that affect the coherence of the project?
@juniorzucareli17 күн бұрын
I think you have to go back a bit and ask yourself, why should I do a unit test on a service class that accesses the database? That doesn't make sense to me. Mocking the database, for me, is a weak test and doesn't have much value. Integration tests should be used for logic that involves the DB in some way. Unit tests work well on domain classes, which have state and behavior, and you don't need a service class for that. Service classes in general are an unnecessary abstraction. Of course, if this service class is called in several places, that's ok. If not, it's an unnecessary abstraction just to follow "by the book." But, if you really want to do a unit test on a service class, just use ef inmemory and your problem will be solved.
@padnom499117 күн бұрын
@@juniorzucareli I don't understand. In lot of project I saw. Generally you have controllers then services ,then the repositories You can have lot of logical in services. Not all projects are with clean ,onion, architecture. So you don't have necessary a domain or application layer. For me a service often can acces to the database but the database should be a detail.
@gui.ferreira13 күн бұрын
As I said in the video, EF with an InMemoryProvider is in fact a Fake.
@julienbarach662018 күн бұрын
What if _store.UpdateAsync(...) throws an Exception ? You still need to surround the code in your UpdateAsync method with try/catch block. Exceptions have a cost, OK, but by definition they don't happen often.
@xaberue19 күн бұрын
Hi Gui! Great video explaining the historial why of the repositories, the sense of having them and/or testing them, and showing an alternative... And yes please, do a video explaining the Specification pattern! Thanks again
@gui.ferreira14 күн бұрын
Glad you enjoyed it!
@WhisperII19 күн бұрын
Great viseo. Would be nice to have a video about specification pattern, thanks!
@gui.ferreira14 күн бұрын
Noted
@piotrkowalski346019 күн бұрын
Please don't unit test repositories. Write integration tests for your use cases with a real database. It will cover your data access testing, whether you use repositories or not. Be pragmatic.
@gui.ferreira13 күн бұрын
As I said in the video. A Repository is a Mapper to an external dependency.
@inkedoo19 күн бұрын
Interesting topic , by the way last week i watched your (NDC) stand talk and its amaaaaaaaazing 👌
@gui.ferreira14 күн бұрын
Thank you so much 😀
@TerkelBrix19 күн бұрын
Yes please to specification pattern 🎉👍👌
@gui.ferreira14 күн бұрын
Ok 😊
@Timelog8819 күн бұрын
The two question that remain in my head: 1. When using domain centric architecture, shouldn't you use interfaces declared in your domain to be implemented by infrastructure logic? How does that work with efcore DBContext? 2. Microsoft explicitly says to not use the in memory provider due to compatibility limitations, what's your reason for promoting it and would you agree using sqlite in memory would still be a unit test?
@juniorzucareli17 күн бұрын
This argument of creating abstraction in the core and implementing it outside of it comes from clean architecture, hexagonal architecture, etc. Usually the argument for this is for the application to be "service agnostic", but in the real world, this is often utopian. - Your application will not change its database. - Your application will not change its framework. - Your application will respond to only its webapi, not to N types of services (queue, mobile), etc. If you have requirements that require you to create abstractions, create the abstraction, but there will be a requirement for this, and do not abstract everything just to follow an architecture. The example in the video is with EF, and it is a very realistic example. Many devs create this abstraction with the repository, which makes no sense at all. EF is already a repository.
@Timelog8817 күн бұрын
@@juniorzucareli I literary am working on a project were it already happened 4! times in the past 2 years in different parts of the codebase. And currently there are talk to also replace elasticsearch so that would be a fifth time. All due to reasons outside our control..... So, often utopian, sure, but I would've been very glad if we would've done it from the start as that would have saved us many headaches.
@gui.ferreira13 күн бұрын
1. The case presented on the Reddit question isn't a case of a domain centric architecture. As the author of the question mentions, he is calling the Repo from the Controller. Domain Centric Architectures change the answer slightly. In a case like that, I want to push the code that interacts with external dependencies to the edges. 2. Can you point me to where Microsoft says that? I confess I never heard about such a recommendation. As far as I know, it's explicit that it's not recommended for production, but only for testing.
@Timelog8812 күн бұрын
@@gui.ferreira Thanks for the comment. For the in memory database, Microsoft mentions that in the documentation about testinf efcore applications: "The in-memory provider will not behave like your real database in many important ways. Some features cannot be tested with it at all (e.g. transactions, raw SQL..), while other features may behave differently than your production database (e.g. case-sensitivity in queries). While in-memory can work for simple, constrained query scenarios, it is highly limited and we discourage its use." As well as in the documentation for the in-memory provider itself. (edit: I tried to add a link but then the comment seems to be auto removed. It you have enabled the option to hold for moderation, then sorry for the spam 🙈)
@z0n_19 күн бұрын
Before people start spamming that these EF-wrapper-repositories are useless. There is real use case for these repositories when you want to restrict access to only specific entities (aggregate roots most likely). EF just gives you way too much freedom when using it for mutations. It's so easy to accidentally skip domain logic when you can just query any entity from any point of tree or fetch the root only partially. I usually use EF only for mutations and query with something else, like Dapper for example (cqrs style).
@Timelog8819 күн бұрын
You don't have to publicly map all entities with efcore though. You can add only the aggregate root to the context and map the rest using the onmodelcreating method. Add that to the fact you can use a separate context for each domain and you really don't need the repository pattern to restrict access.
@z0n_19 күн бұрын
@@Timelog88 You can still query every entity in context with `DbContext.Entry<TEntity>()` or with `DbContext.Find<TEntity>()` and you get access to `DbContext.Add` and `DbContext.AddRange`. So you are not really restricting anything unless you are willing to make every non-aggregate-root entity `internal`. "you can use a separate context for each domain" - I am talking inside a single bounded context.
@z0n_18 күн бұрын
You can still query every entity in context with `DbContext.Entry<TEntity>()` or with `DbContext.Find<TEntity>()` and you get access to `DbContext.Add` and `DbContext.AddRange`. So you are not really restricting anything unless you are willing to make every non-aggregate-root entity `internal`. "you can use a separate context for each domain" - I am talking inside a single bounded context.
@Timelog8818 күн бұрын
@@z0n_ Quite sure you can't with good encapsulation. Will check if I can get an example up and running tomorrow.
@yaghiyahbrenner890220 күн бұрын
This nonsense started with Java and followed by DDD books for enterprise corp coders, its dead. use a Dao NH Session(), EF Context() are by nature a Repository, the years of people writing classes on top of classes..
@krccmsitp288419 күн бұрын
The repository in DDD is different to "other" repositories.
@yaghiyahbrenner890219 күн бұрын
Hate it all. abstractions with no benefits. If you work with large data sets, you end up with direct calls to the db with optimizations.
@relicsoft19 күн бұрын
Make sense.
@RonaldCabreraGonzalez20 күн бұрын
Please do the video about specification pattern, also your view about unit tests was pretty constructive.
@Rick10454720 күн бұрын
Yeah would love to see it. Working with an architect currently who insists on using that pattern but we end up going through all kinds of hoops to get back the support for certain operations that you already have normally. We have to use ardalis for it though and are not allowed to use an alternative way. I would much prefer using extension methods and you could even go the delegate way if you really need to inject specifications somewhere.
@gui.ferreira14 күн бұрын
Added to the pipeline 😉
@Enygma200222 күн бұрын
So the industry gave up on checked exceptions and then realized that code can fail without the caller knowing about the potential failure points. Now we're coming up with an entire new concept (that BTW loses the stack trace information), all to avoid just using checked exceptions that the language supports by design?
@gui.ferreira21 күн бұрын
Not really… there's a place for exceptions. I have a video on it here kzbin.info/www/bejne/mXzEZ6F5qs1qmcU
@HeellFighter22 күн бұрын
¿Why do you recommend using a library? Because that is the approach i want to take but it´s hard to pitch it to the team.
@gui.ferreira21 күн бұрын
I tend to adopt solid libraries. I prefer to contribute to the ecosystem than build myself. However, if bringing a new library is friction, for such a small feature, I would build my simple version of it.
@aerisseon22 күн бұрын
I believe it is because the navigator did an excellent job of directing (using) chatGPT. Meaning, it is also in the user how well they know their craft. But that is indeed amazing demo of the crazy capabilities of the GPT.
@gui.ferreira21 күн бұрын
Experience will play a role for sure. Master your tools even if they are AI 😉
@rekarpcpro22 күн бұрын
Thanks for your video. I like these design pattern videos.
@gui.ferreira21 күн бұрын
Thank you! Any pattern you want to understand better?
@rekarpcpro20 күн бұрын
@@gui.ferreira Ok, there are a lot of questions in my mind that I don't have a standard way to do it. Just one of them is, let's say, we have orders controller that have a route to return an individual order. Should you include the list of order items for that order in the DTO model? or you should have another route to get order items separately? What if the item has a translations (list) field? Should you include (joining tables) for each order item while fetching the list of order items? I wonder what your standard is for creating DTO in complex systems (microservices).
@ecuyar24 күн бұрын
Good explanation thanks. How can I identify the real problem for ex. an exception is throwed and I want to log it? Aren't we ignore valueable exception data by using Result pattern?
@gui.ferreira21 күн бұрын
The idea is that you only replace exceptions that are not that “exceptional”. That means that you have the Result pattern on the expected paths. You can still produce telemetry there. The difference is that doesn't come from a bulky exception. But, do I need something like the stack trace for an expected case?!
@ecuyar20 күн бұрын
@@gui.ferreira Right, maybe we need bulky exceptions in the first phases of the project but not in the final product. Thanks.
@MichaFita24 күн бұрын
Rust influencing C# as well? 👍
@gui.ferreira21 күн бұрын
It's good to absorb what others do right 😉
@MichaFita21 күн бұрын
@@gui.ferreiraCouldn't agree more.
@commander319224 күн бұрын
Great video. I fear looking at the code of the people saying "but why".
@dirtyworkinc25 күн бұрын
it feels unnatural in C# community, but this is all until Microsoft would finally implement descriminated unions feature. Nick Chapsas just had great video reviewing proposal feature even with some code examples and details. Not sure I am happy that part of the feature works using reflection in runtime, but this is still pretty solid step.
@antonmartyniuk26 күн бұрын
+1 for result pattern
@10Totti26 күн бұрын
Great tutorial thanks!
@gui.ferreira26 күн бұрын
Glad you enjoyed it!
@ldeerosel26 күн бұрын
i Always use Result<T,E> and my implementation have methods like Rust(map, bind,unwrap and so on). I love It, but i can t use It with my team 😢
@gui.ferreira26 күн бұрын
You are not alone 😔
@padnom499126 күн бұрын
Thanks a lot for your video. I agree that readability is the main advantage of the result pattern or monad. Exception can be see as a Go To. A good video on this topic is "Throw Exceptions Out of Your Codebase" by Guillaume Faas. However, performance should not be the deciding factor. I conducted a benchmark and found that the difference is not significant.
@gui.ferreira26 күн бұрын
Performance is not the main reason. Can you share your benchmark? I and others have done exactly that already and came up to exactly the opposite conclusion. I would love to take a look.
@padnom499125 күн бұрын
@@gui.ferreira hello I try to respond to your comment but look like something is not compilant with youtube. I don't know how to share the repos ...
@NoName-lu7jf26 күн бұрын
6:47 no rickroll? :(
@isachellstrom846726 күн бұрын
I like how you talk about the pros and the cons, this honestly seems situational but not really scalable
@gui.ferreira26 күн бұрын
I would say it's harder in big teams.
@werterdotnet26 күн бұрын
This video is proof that my studies and thoughts are on the right track. I managed to have the same idea, the same conclusion as an MVP star.
@gui.ferreira26 күн бұрын
Where's the star? 🤓 I love the fact that great ideas tend to naturally emerge with experience.
@FB-eb6tx27 күн бұрын
Great content! Thanks like always!
@gui.ferreira26 күн бұрын
My pleasure!
@pawegruba471927 күн бұрын
Result Pattern, Result Pattern, but remember it is not a solution for all issues. If you have complex logic, multiple level of call hierarchy, and any issue in the code will break the whole execution, there is no need to use Result Pattern and mess your code with thousands of if(result.Success) but it is much better just to throw an exception, catch and handle in global exception, and keep your code clean and readable
@stefano_schmidt26 күн бұрын
just don't write nested messy code, and your problem is solved 👍
@AkosLukacs4226 күн бұрын
Instead of checking result.Success, you can introduce Result.Map and Result.MapError functions, and it's clear that you handle the successful or unsuccessful case. And helpers / implicit operators to help with repetitive error cases. Check out railway oriented programming, if you are curious.
@AkosLukacs4226 күн бұрын
And the post titled "Against Railway-Oriented Programming" for a full picture!
@marko5734Сағат бұрын
Isn't that the best use case for the result pattern? In a multiple level of hierarchy you don't want to always throw exception beacuse based on some response type you don't want to stop the flow of the program.
@adrian_franczak27 күн бұрын
This - I have my own implementation (unfortunately) in company code base but it fulfills the goals of don’t throw if you can return error The only unsolved problem due to time constraints is what if want to have different behavior based on error code (rn it is ugly if statement in a few places) To be satisfied with result type in .NET you need to add a little bit of ext method on Task type also you can chain them if you want to
@gui.ferreira26 күн бұрын
Exactly. Maybe with discriminated unions, it will be easier 🤞