How to create your own Fluent API in C#

  Рет қаралды 51,137

Nick Chapsas

Nick Chapsas

2 жыл бұрын

Become a Patreon and get source code access: / nickchapsas
Check out my courses: dometrain.com
Hello everybody I'm Nick and in this video I am going to show you how you can create your own Fluent API in C# and .NET. This is one of the many methods you can follow to do it but it's one of my favourites because it gives you the ability to have stages in your fluent building.
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

Пікірлер: 136
@owns3
@owns3 2 жыл бұрын
Remember watching this forever ago, but for some reason, didn't have it liked!? Re-watched and worth the like!
@jackkendall6420
@jackkendall6420 2 жыл бұрын
Very glad you included the final bit on the lambda-syntax bit some APIs use, always been curious how to implement it!
@brianm1864
@brianm1864 2 жыл бұрын
Great video! I did the simple method for creating a fluent API for generating test data for our unit tests, which the other engineers love. But I really like your more controlled way of forcing them down a particular path. With the way mine currently is, the developer could create bad data. I may have to update it now!
@drac.96
@drac.96 Жыл бұрын
This is technical gold. Library and application authors will have a good time using these builder and config pattern techniques. Thanks Nick!
@michaelhochriegl9501
@michaelhochriegl9501 2 жыл бұрын
Awesome demonstration! Will defo use this approach from now on.
@LOrealHardly
@LOrealHardly 2 жыл бұрын
I've been looking for this for so long! Thank you so much, Nick!
@kaiserbergin
@kaiserbergin 2 жыл бұрын
works great for creating test data for complex object as well. thanks for sharing, when i found out you could do this stuff, it really changed the way i approach writing parts of my projects
@thatcreole9913
@thatcreole9913 2 жыл бұрын
I never realized I wanted to use this pattern until this video. Awesome!
@andersborum9267
@andersborum9267 2 жыл бұрын
Great idea using segmentation by seperating the responsibilities to seperate interfaces; leads to a much more fluent (and predictable) use.
@SimonVane
@SimonVane 2 жыл бұрын
Isn't that exactly what he did? I'm missing what you're getting at and I'm keen to learn if there's a better way
@rhw14
@rhw14 2 жыл бұрын
@@SimonVane I think Anders is saying that what Nick did was a great idea
@SimonVane
@SimonVane 2 жыл бұрын
@@rhw14 Ah, I see. I misunderstood. That makes more sense 😁
@akeemaweda1716
@akeemaweda1716 2 жыл бұрын
Love the second method. Never thought of that! Thanks a bunch Nick.
@RichardONeil
@RichardONeil 2 жыл бұрын
Perfect demonstration! Thanks Nick!
@SadPraetorchannel
@SadPraetorchannel 2 жыл бұрын
This is my first ever comment on KZbin. And I make this effort to thank you. Your content rocks!!!
@hesamkalhor3263
@hesamkalhor3263 2 жыл бұрын
Man, your content is awesome! thank you for creating these videos.
@pedroxpdo
@pedroxpdo 2 жыл бұрын
Your content is such a master piece always worth watching
@alexvanheerden5702
@alexvanheerden5702 2 жыл бұрын
I've been trying to implement something like for some time and was the missing piece of the puzzle, THANK YOU.
@DraaElMizan
@DraaElMizan Жыл бұрын
Great content as usual. Thanks Nick.
@edmonddantes587
@edmonddantes587 2 жыл бұрын
always wondered how this was done. Thanks Nick.
@kano636
@kano636 2 жыл бұрын
similar concept but a different approach could be achieved by using extension methods... not so safe and intuitive as your solution, but it's a wrapper we could use to create a fluent API around a third party code we are using. great video Nick!
@imranketamashay
@imranketamashay 2 жыл бұрын
pure piece of mastery. learned a nice trick from you today
@amnesia3490
@amnesia3490 2 жыл бұрын
I really appreciate your work on the contents
@Radictor44
@Radictor44 2 жыл бұрын
thanks Nick for sharing your knowledge
@nove1398
@nove1398 2 жыл бұрын
I like this guided approach
@mihaimyh
@mihaimyh 2 жыл бұрын
Nice one again, thanks for these videos.
@reveme
@reveme 2 жыл бұрын
I definitely agree with who says that for example like this the builder pattern is unneeded boilerplate. It can have a reason only with branches and optional steps. In this simple case a factory method is all you need
@nasserhossam1
@nasserhossam1 Жыл бұрын
Very helpful, thanks !!
@compman73
@compman73 2 жыл бұрын
Thanks for your lovely video 👍👍
@d-kay6668
@d-kay6668 2 жыл бұрын
For those of you having difficulty wrapping your head around understanding the invoking of the configuration: Think of the Action as a builder for whatever you replace T with. You're effectively presenting the user with a way to initialize the object. Then you're applying that initialization to an existing object, filling it with whatever was entered into the builder.
@reneschindhelm4482
@reneschindhelm4482 2 жыл бұрын
Basically, you hand the object you create inside the method out to the caller. Still this specific pattern/way of configuring feels very strange to set up and trips me up 😅
@joesaraceno9825
@joesaraceno9825 2 жыл бұрын
Could it be likened to something like injecting the config values into the scope of the class? Maybe like a JavaScript .apply()?
@voidar
@voidar 5 ай бұрын
You can also simply call config(configuration)
@branislavpetrovic7486
@branislavpetrovic7486 2 жыл бұрын
Nice one! Thanks.
@noodle-eater
@noodle-eater 2 жыл бұрын
Awesome, I always curios how to make those kind of method
@edwintorres2577
@edwintorres2577 2 жыл бұрын
It looks like an elegant simple class, but I like it!!!
@AnthonyMaddenVRStudio
@AnthonyMaddenVRStudio 2 жыл бұрын
I’ve always wanted to learn how to program this way 😍😍😍
@kanamefudoshin6127
@kanamefudoshin6127 Жыл бұрын
Great video! I would like to know whether this pattern can be applied to asynchronous operations like database queries and if yes, maybe I would love to see a video featuring it please. 😄
@Eugene.g
@Eugene.g 2 жыл бұрын
such a great clean pattern
@BigBrainHacks
@BigBrainHacks Жыл бұрын
Love the video!
@philc8544
@philc8544 2 жыл бұрын
Great stuff 👏
@matteobarbieri2989
@matteobarbieri2989 2 жыл бұрын
💣💣💣so great💣💣💣 Can't wait to implement...
@Dimonina
@Dimonina 2 жыл бұрын
2021. The old builder pattern is now called a modern word "fluent api" ))))))))))
@Deathhead68
@Deathhead68 2 жыл бұрын
I find this a lot with so much new stuff, it looks really confusing but once you look under the covers, it's doing something you've seen before. I don't mind though, because a lot of the time it's doing it well.
@liquidvapour
@liquidvapour 2 жыл бұрын
@@Deathhead68 that is called experience 😅
@georgehelyar
@georgehelyar 2 жыл бұрын
See Kevlin Henney - Old is the new new
@promant6458
@promant6458 2 жыл бұрын
FluentAPI and builders are not the same thing, the terms are not interchangable. All builders are FluentAPI, not all FluentAPIs are builders.
@Deathhead68
@Deathhead68 2 жыл бұрын
@@promant6458 yeah, it's just a type of builder pattern though.
@kblyr
@kblyr 2 жыл бұрын
I actually use this pattern, my code looks so clean
@KieranDevvs
@KieranDevvs 2 жыл бұрын
Give yourself a pat on the back?
@skydrow4523
@skydrow4523 2 жыл бұрын
@@KieranDevvs Comment once you have something interesting to say
@KieranDevvs
@KieranDevvs 2 жыл бұрын
@@skydrow4523 Something interesting.
@ibnfpv
@ibnfpv 2 жыл бұрын
Great video!
@ardavaztterterian1211
@ardavaztterterian1211 2 жыл бұрын
Hello Nick. Can you make some videos regarding microservices and domain driven design?
@_torgeek9108
@_torgeek9108 2 жыл бұрын
Nick is Uncle Bob's secretary. We just don't know about it🙂. Thanks again for this great video Nick.
@clashclan4739
@clashclan4739 2 жыл бұрын
Hope you won't delete all your videos over night 😭. Very useful content pls do more like this.
@JPBInFL
@JPBInFL 2 жыл бұрын
Great video Nick. Does raise a question. You have walked the user through the creation of your object. The user now attempts to call some method on the object. The method is of course shown in IntelliSense, but all the creation helpers also show up. If the user were to use one of them, he's returned that interface, at that point. Certainly the user should know not to do this, but sure would be cool if there were some ingenious way to hide those on the created object reference.
@denisadimov7709
@denisadimov7709 2 жыл бұрын
Good sample Fluent API usage. Can you show samples of building complex objects? I often use Fluent API for it, is it a good workaround?
@noblenetdk
@noblenetdk 2 жыл бұрын
Great as always. But I have to see it once more - didn't get how to fork the options.
@alexbarac
@alexbarac 2 жыл бұрын
In Nick's example, the interface containing the "AsUser" method would also contain, say a "WithToken" method, passing a token as a parameter and would then return another interface, say ITokenConnectionInitializerStage, instead of the IPasswordSelectionStage interface. So something like: public IUserSelectionStage { public IPasswordSelectionStage AsUser(string user); public ITokenConnectionInitializerStage WithToken(string token); } This will allow the user to connect directly after specifying the token, it will "hop" over the IPasswordSelectionStage. Of course, the IUserSelectionStage will require a different name. The new ITokenConnectionInitializerStage would have the same Connect method as IConnectionInitializerStage, just it's implementation would be different, since you now connect via a token instead of a user and pass, so you need to configure your connection string differently. I hope this makes sense!
@TreeLuvBurdpu
@TreeLuvBurdpu 2 жыл бұрын
This seems like a functional F#-like type-pipelining method of functional guidance. Do you do anything with F#, Nick? Videos?
@ryanzwe
@ryanzwe 2 жыл бұрын
Hey Nick, is there a good way to contact you in regards to some career advice if you do that
@Pixalynx
@Pixalynx 2 жыл бұрын
Hey Nick, I was wondering if you could do a tutorial or if it was possible to do extension methods on the interfaces?
@AngusMcIntyre
@AngusMcIntyre 2 жыл бұрын
Extension methods are only useful when you want to provide commonly used actions over a very extensible interface. IServiceCollection and IEnumerable are great examples. The interface itself is very powerful but clever operations require clever code that we dont want to type every time. As a massive bonus, you don't need to modify trhe concrete type to add this behavior.
@shreyasjejurkar1233
@shreyasjejurkar1233 2 жыл бұрын
Interesting and very thanks, Nick. This pattern is heavily for startup configuration in aspnetcore. But am also searching for another way of implementation, creating a type for setting up each individual field insider builder is quite a concern to me. Is there any other way are you (or anyone) aware of?
@bycrookie5248
@bycrookie5248 2 жыл бұрын
just ceate an object and hold it in the builder and set the properties on the object and return it on the last method -- The object in the builder class private IWorkflow _workflow; --Constructor public WorkflowBuilder() { _workflow = new Workflow(); } -- The last method build public IWorkflow Build() { var workflow = _workflow; _workflow = new Workflow(); return workflow; }
@Layarion
@Layarion 2 жыл бұрын
I like your funny words magic man, but does having all of this in one statement line make debugging harder? also, this is pretty cool. easy to follow and read.
@2SHARP4UIQ150
@2SHARP4UIQ150 2 жыл бұрын
As it happens, builder is a creational design pattern that is a good choice for a developer to use for creating a fluent API. Both are different thing.
@xOdiee
@xOdiee 2 жыл бұрын
good shit nick
@simoneurbani3303
@simoneurbani3303 2 жыл бұрын
Nice video as always! I have a little question: in this case the code we write to allow the user to build our class can be very long (I guess). Is a better practice create a static class 'MyClassBuilder' (and no public constructor in the actual class) or create a builder static method inside the class?
@jackkendall6420
@jackkendall6420 2 жыл бұрын
If you had no public constructor in the actual class, MyClassBuilder wouldn't be able to instantiate it either. I think the static class idea is better, you just accept that people will be able to instantiate the main class directly if they want to. I guess if you're publishing a library, you could make the constructor internal?
@simoneurbani3303
@simoneurbani3303 2 жыл бұрын
@@jackkendall6420 There's no friends class in c#? (I moving from c++ to c# recently)
@jackkendall6420
@jackkendall6420 2 жыл бұрын
@@simoneurbani3303 There aren't. There are friend assemblies (one assembly can see internal stuff in another), but not friend classes. If a class have a private constructor, that's it, nobody else can call it. (Except through reflection)
@simoneurbani3303
@simoneurbani3303 2 жыл бұрын
@@jackkendall6420 ok thanks!
@majormartintibor
@majormartintibor 2 жыл бұрын
I think I followed along just correctly, but when I am at FluentSqlConnection.CreateConnection(). intellisense offers me all steps instead of only ForServer(). All further steps work as they should. Can't figure out where I went wrong.
@Schnickalodeon
@Schnickalodeon 2 жыл бұрын
Very interesting Video! What would I do if one Step is optional?
@voidar
@voidar 5 ай бұрын
Nullable? Or the optional ones return its receiving interface/stage.
@junejasaket
@junejasaket 2 жыл бұрын
How do you effectively write Unit Tests for this approach? I always find it tricky to write tests for the Builder pattern as it requires private fields.
@nickchapsas
@nickchapsas 2 жыл бұрын
Actually writing unit tests for this is extremely easy because they are based purely on interfaces so you have absolute control
@Mmbow
@Mmbow 2 жыл бұрын
hoo interesting thank you....
@fanturyP
@fanturyP Жыл бұрын
Excelente
@terencetcf
@terencetcf 2 жыл бұрын
I like fluentapi, but sometimes is annoying when on of the step has error in runtime which you don’t get the error line at quick glance instead it only tells you the error starts from line 1…
@SebGruch
@SebGruch 2 жыл бұрын
I see this, interesting ways. Yet I still prefer simple class with some properties, just throwing null-ref when mandatory field is not set :-P
@scottburfield-mills8249
@scottburfield-mills8249 2 жыл бұрын
That works but you wouldn't find out the failure until runtime. A benefit of this approach seems to be you wouldn't be able to reach 'Connect' method without setting the necessary fields. It cuts out the need to know how the class really works because the IDE is going to force you to configure the things you are required to.
@rubayethkamal210
@rubayethkamal210 2 жыл бұрын
How would you implement this for asynchronous api ?
@nickchapsas
@nickchapsas 2 жыл бұрын
In the same way but instead of returning the result you would return the Task of the result and in the mid sections you woudl return Func
@samwalker5438
@samwalker5438 2 жыл бұрын
How timely, I was just using this pattern yesterday. I do have a question though. I have classes with collections of child objects but a I struggle to find a clean way to build those child collections using fluent style. Any suggestions for that?
@babri1402
@babri1402 2 жыл бұрын
Some more detail would be needed about your specific problem statement. What exactly are you struggling with while implementing it in fluent way?
@bycrookie5248
@bycrookie5248 2 жыл бұрын
if i understand correctly, you could make another method just called add, and then add it to the collection. you just have to call the method on the fluent api multiple times
@edreeve7188
@edreeve7188 2 жыл бұрын
Further to that, you could create the 'AddChildObjects' method using the `params` keyword, which would allow an array or comma separated list of arguments to be passed in, populating the collection in one go
@jexrabbit
@jexrabbit 2 жыл бұрын
Great video, as always, but I just can't see the need for this of pattern. Same with the object initializers with new object { Property = ... }. I think the old-fashioned way of instantiating an instance of a class and then setting its properties and calling its methods one-by-one is cleaner. Maybe I'm old school? ;)
@BillieJoe512
@BillieJoe512 2 жыл бұрын
I really like the object initializers for instantiating nested objects and collections. additionally in combination with the init only setter you can make a defacto read-only property that can only be set at construction without the need of a constructor.
@yaghiyahbrenner8902
@yaghiyahbrenner8902 2 жыл бұрын
read the documentation. set the configuration.
@KelvinNishikawa
@KelvinNishikawa 2 жыл бұрын
How are optional stages handled?
@nickchapsas
@nickchapsas 2 жыл бұрын
With stages that return back to the current stage instead of the next one
@taavipaal7440
@taavipaal7440 2 жыл бұрын
How would you add optional methods to the fluent API? E.g. the user has a firstname and lastname and optionally a middlename.
@nickchapsas
@nickchapsas 2 жыл бұрын
The optional path would return back in the previous state
@prouleau4440
@prouleau4440 2 жыл бұрын
@@nickchapsas Maybe I am missing something too obvious, but I think that would get us stuck at the "set name" stage and we would not be able to reach the "connect" stage. Maybe overloads in "set name" stage would be better, like "setUser(firstName, lastName)", "setUser(firstName, middleName, lastName)" and all overloads return the next stage.
@gopinathnath6747
@gopinathnath6747 2 жыл бұрын
@@nickchapsas Can you give some example for this. I couldn't figure it out. Currently, my call is like firstName().MiddleName().firstName().LastName(). I could set lastName as next stage, I will get firstName().MiddleName().LastName(). But, what I want to have two optional middleName?
@alcar32sharif
@alcar32sharif 2 жыл бұрын
Eric Evans and Martin Fowler (founders of fluent interfaces in 2005) call this explicitly a "fluent interface". Where does the name *fluent api* come from?
@nickchapsas
@nickchapsas 2 жыл бұрын
Api stands for application programming *interface*. They just omitted the AP because it is kinda redundant but helpful when you’re explaining the concept
@pranesh-sekar
@pranesh-sekar 2 жыл бұрын
So are we creating the classes this way for ease of use with the intellisense??? to get a sequencial order of methods
@simoneurbani3303
@simoneurbani3303 2 жыл бұрын
Intellisense helps you to see which methods are available, but if you switch the methods order your code won't compile, with or without intellisense
@pranesh-sekar
@pranesh-sekar 2 жыл бұрын
@@simoneurbani3303 i looked at the video again. What i understood is the order in which we call the methods depend on the order in which the interfaces are inherited, am i correct? While using the wrong order, the ide throws error that the method is not defined
@simoneurbani3303
@simoneurbani3303 2 жыл бұрын
@@pranesh-sekar correct
@prouleau4440
@prouleau4440 2 жыл бұрын
​@@pranesh-sekar Small correction: the order of the inheritances is not important. The order is enforced by the return type of each method and since you have to call CreateConnection() first, the rest follows.
@pranesh-sekar
@pranesh-sekar 2 жыл бұрын
@@prouleau4440 got it. Hard to notice. Each method has the next interface as the return type
@mihaimyh
@mihaimyh 2 жыл бұрын
What if there are optional properties for an object?
@nickchapsas
@nickchapsas 2 жыл бұрын
Then you can have them in levels that it’s appropriate but feed the result back to the previous node in the chain
@geoffreycallaghan9649
@geoffreycallaghan9649 2 жыл бұрын
When I was a mid level programmer, I showed some similar code to my Boss with an equal amount of abstractions and "magic", to which he replied. You need all that code , just to write some shit to the database? I was offended, but he was right! Now I use simpler languages than C#. Fuck inheritance !
@clearlyunwell
@clearlyunwell 2 жыл бұрын
👍🏽
@AlanDarkworld
@AlanDarkworld 2 жыл бұрын
Builders like this are great, but are sometimes really hard to debug ("Why did my config end up looking like this?" or "Who set this field to this value?"). Also, if you are writing a builder yourself and your config gets more complex, you might be inclined to create an abstract "Stage" class and separate things out. Now you run into a big issue: the return value for all methods in the abstract stage class is always "this". But the C# type system can't express the type "Self" (nor can Java, or Kotlin for that matter). Then, you'll need the "self-curious generic" (e.g. en.wikipedia.org/wiki/Curiously_recurring_template_pattern, works more or less the same way in C#, Java, Kotlin etc.). And then things get really complicated really quickly.
@cyrildouglas9262
@cyrildouglas9262 2 жыл бұрын
Are access modifiers really needed inside interfaces?!, as far as I know all members of interfaces are public.
@galandilvogler8577
@galandilvogler8577 2 жыл бұрын
No, they are not. But imo it's a good habit that improves readibility, much alike using `private` before any private member instead of omitting it.
@bycrookie5248
@bycrookie5248 2 жыл бұрын
you are right, i never use them in interfaces
@promant6458
@promant6458 2 жыл бұрын
Since C# 8 interface members don't need to be public.
@derinteressierte8732
@derinteressierte8732 2 жыл бұрын
endlich sieht man die gehirn gewaschenen ))
@ThekillingGoku
@ThekillingGoku 2 жыл бұрын
I have nothing against the fluent approach and this was a nice demo on ways to cleanly implement it. However, for the example given I would still prefer a simple constructor (or most likely factory pattern) w/o needing a whole bunch of seperate method calls just to pass in 4 parameters. Heck, via connection string it'd be just 1 param, but I digress. I seriously would dislike needing 4/5 lines each time I need 'using connection X' to make a connection, so yeah. You'd just end up throwing those 5 lines in a seperate method anyway so you don't have to write the 5 lines each time. And as such ... you'd likely end up at a factory approach where the Factory.CreateConnection(4 params) contains the 5 or 6 lines of fluent stuff. The fluent stuff, with distinct interfaces for intermediate returns, does become more interesting the more branches you have (and as such, the more overloads you'd need to do it via params).
@androidsavior
@androidsavior 2 ай бұрын
please share the source code
@amnesia3490
@amnesia3490 2 жыл бұрын
Can anyone share me the documentations by microsoft about this topic if exist ?
@nickchapsas
@nickchapsas 2 жыл бұрын
This isn’t a Microsoft thing so there isn’t any Microsoft specific documentation
@AhmadHddad01
@AhmadHddad01 2 жыл бұрын
Great video Can someone post the code Thanks
@nickchapsas
@nickchapsas 2 жыл бұрын
The code is only available to my Patreons
@mihaimyh
@mihaimyh 2 жыл бұрын
Can you share the source code, please?
@nickchapsas
@nickchapsas 2 жыл бұрын
The source code for all my videos is available for my Patreons
@djod1751
@djod1751 2 жыл бұрын
I'm unconvinced that the Builder pattern is any good. In all implementations I've seen, they give you the illusion of being useable with out understanding of the implementation. The minute you try and do something complex, unsupported, or just different to how the api expects, you are lossed. You are have to understand the api's workings anyway, except now the api is far more difficult to understand. Now you have to understand many implentation specific interfaces, generic functions, and delegates that do simple things like setup a few properties, but in the most complex way. Keep it simple stupid.
@microtech2448
@microtech2448 2 жыл бұрын
You directly jump into explanation without any prior agenda, requirement, what would be end result, why and how this will help or different. All messy.
@AdroSlice
@AdroSlice 2 жыл бұрын
ew
@clearlyunwell
@clearlyunwell 2 жыл бұрын
👍🏽
Don't throw exceptions in C#. Do this instead
18:13
Nick Chapsas
Рет қаралды 248 М.
Como ela fez isso? 😲
00:12
Los Wagners
Рет қаралды 33 МЛН
🍕Пиццерия FNAF в реальной жизни #shorts
00:41
How to write "smarter" enums in C#
12:56
Nick Chapsas
Рет қаралды 133 М.
What is Span in C# and why you should be using it
15:15
Nick Chapsas
Рет қаралды 247 М.
The New .NET 9 HybridCache That You Must Upgrade To!
14:34
Nick Chapsas
Рет қаралды 41 М.
The evolution of Pattern Matching in C# (from version 6 to 10)
16:08
You are doing .NET logging wrong. Let's fix it
25:29
Nick Chapsas
Рет қаралды 168 М.
BEST WAY to make Desktop Applications in C++
26:00
The Cherno
Рет қаралды 876 М.
Every feature added in C# 10 with examples
15:59
Nick Chapsas
Рет қаралды 124 М.
"Stop Using Async Await in .NET to Save Threads" | Code Cop #018
14:05
10 C# Libraries To Save You Time And Energy
33:59
IAmTimCorey
Рет қаралды 204 М.