Пікірлер
@incubated
@incubated 9 күн бұрын
thanks. came in really handy. we started working on an authorization microservice, recently.
@JeffZuerlein
@JeffZuerlein 9 күн бұрын
Glad to hear it!
@davood7497
@davood7497 13 күн бұрын
Good job !
@JeffZuerlein
@JeffZuerlein 9 күн бұрын
Thanks!
@davood7497
@davood7497 16 күн бұрын
Good Job !
@JeffZuerlein
@JeffZuerlein 15 күн бұрын
Thanks!
@massinamas
@massinamas 17 күн бұрын
What is the difference between groups and roles?
@JeffZuerlein
@JeffZuerlein 16 күн бұрын
To me...They are completely different, to Microsoft, they are the same thing. My notion of a Role would be the personal assistant to a CEO, or the CEO. It's a job that gets filled by a user. I don't want to code rights to an individual user, but I would to a role. My notion of a group would be a set of users. That set of users could all be given the same right, or the group could be assigned to a role. An example would be... Role = Online Content Reviewer, and there could be a group of users who fill that role. Microsoft doesn't support relationships between users, roles, groups, and tenants. I think it makes managing authorization much easier.
@Vallecaucanisimo
@Vallecaucanisimo 17 күн бұрын
Hello Jeff, Thank you very much for the video. I just wish that I wasn’t so inexperienced so that I could fully make use of it. If you are looking for more video topics, please consider making a tutorial for authentication and authorization for the absolute beginner in c#. There are so many methods and services, and it can be quite intimidating should you get it wrong and the app is vulnerable. I’ve been working on a Maui Blazor app and I will need to add authentication soon but I’m lost on the best approach. Thank you!
@JeffZuerlein
@JeffZuerlein 16 күн бұрын
My suggestion would be to use the Authentication options that come with AspNet applications out of the box. They are a great starting point, and Microsoft generally leads you down good path. learn.microsoft.com/en-us/aspnet/core/blazor/security/?view=aspnetcore-8.0 This whole .net ecosystem is intimidating, but there's lots of guidance!
@ugochukwuumerie6378
@ugochukwuumerie6378 18 күн бұрын
Thanks you for this video. I have always needed this explanation
@JeffZuerlein
@JeffZuerlein 17 күн бұрын
You're very welcome!
@ugochukwuumerie6378
@ugochukwuumerie6378 21 күн бұрын
Awesome 👍. Can't wait for the rest of the series. Thank you
@JeffZuerlein
@JeffZuerlein 21 күн бұрын
More to come!
@user-yi5lh4en9t
@user-yi5lh4en9t 21 күн бұрын
That was very insightful, thanks. Could you please create a video about Permission-Based Authorization
@JeffZuerlein
@JeffZuerlein 21 күн бұрын
I appreciate that! I'll put it on the list. Are you working on implementing permissions in an application, or looking for an alternative to what you're working with?
@MadaFakaTOO
@MadaFakaTOO 21 күн бұрын
Why not just do "SELECT * FROM REVIEWS WHERE ReviewerId == LoggedUserId" when showing reviews?
@ProstoDoCelu316
@ProstoDoCelu316 29 күн бұрын
you will make call to database on every request right?
@JeffZuerlein
@JeffZuerlein 28 күн бұрын
Yep. Caching could be a good option. Typically application specific claims don’t change very often. That would reduce the round trips and latency.
@krccmsitp2884
@krccmsitp2884 29 күн бұрын
That was very insightful, thanks. I'd like to see more about implementing authorization topics.
@JeffZuerlein
@JeffZuerlein 28 күн бұрын
I’m working on it!
@vladans
@vladans Ай бұрын
Hi Jeff, I'm interested in an extended series on authorization. Also, I'm interested in the code samples that you use in the presentations. Many thanks
@JeffZuerlein
@JeffZuerlein Ай бұрын
I'm working on another that covers resource based authorization, then maybe a deep dive internals of Authorization.
@vladans
@vladans Ай бұрын
​@@JeffZuerlein great, thanks for the quick response.
@ugochukwuumerie6378
@ugochukwuumerie6378 Ай бұрын
Yesss, go ahead. Also on a webapi application too
@JeffZuerlein
@JeffZuerlein Ай бұрын
I could do that.
@donatasbielskis2083
@donatasbielskis2083 Ай бұрын
Thank you
@JeffZuerlein
@JeffZuerlein Ай бұрын
You're welcome
Ай бұрын
Thank you! I worked with all components but it never crossed my mind to combine them like this. And it makes perfect sense
@JeffZuerlein
@JeffZuerlein Ай бұрын
I know! I can’t figure out why people don’t talk about it more.
@alexisfibonacci
@alexisfibonacci Ай бұрын
How about implementing the IClaimsTransformation interface?
@JeffZuerlein
@JeffZuerlein 16 күн бұрын
I've been avoiding your comment for long enough... You could use the IClaimsTransformation interface to "Decorate" or "Transform" a ClaimsPrincipal, in a very similar way to what I describe in my video. I presented the option of using middleware because a while back I read Brock Allen's blog post on the transform occurring more than once per request. However, I recently learned that Microsoft added a HashSet to the AuthenticationService to cache the result of the transform, so it effectively only gets transformed once. github.com/dotnet/aspnetcore/commit/814a37548b6adae2f846eae3144e8f37c1388520 That makes IClaimsTransformation much more compelling. At the end of the day, both work. I think the differentiator between the two options are...Do you need the HTTPContext in the decoration process? Do you need to implement your own caching of ClaimsPrincipal data for performance reasons, if so where and how? I still think there could be a slight performance advantage to using the middleware approach, but I don't have data to support that.
@andrejsk6211
@andrejsk6211 Ай бұрын
A video about resource based authorization would be useful :)
@JeffZuerlein
@JeffZuerlein Ай бұрын
Yes…
@cuongphung9163
@cuongphung9163 Ай бұрын
The way you organize content and present are great. Thanks so much
@JeffZuerlein
@JeffZuerlein Ай бұрын
So nice of you to say. I appreciate it.
@obinnaokafor6252
@obinnaokafor6252 Ай бұрын
Nice video. Please could you do some videos on collection expression and type aliases, including Vectors and Intrinsics in C#?
@JeffZuerlein
@JeffZuerlein Ай бұрын
Thank you! I’m curious what’s you use case for Vector of T?
@obinnaokafor6252
@obinnaokafor6252 Ай бұрын
@@JeffZuerlein used in computation and machine learning as well gaming
@07309415
@07309415 Ай бұрын
Thanks for video. I like how you explained the material and would like to see more on this subject. I appreciate access to the source as well.
@JeffZuerlein
@JeffZuerlein Ай бұрын
Thank you! I want to make one or two more videos on Authorization, so I’m working on cleaning up the source code and adding a few more examples. Glad you liked the content!
@JoshOlsonDev
@JoshOlsonDev Ай бұрын
Awesome video series Jeff! Looking forward to more optimization tips for retrieving data from SQL Server via .NET/Dapper. One thing not covered in your benchmark that may be worth comparing is `ToLookup()` vs. `GroupBy().ToDictionary()` -- one nice thing is you can simplify your code in that you don't have to do `TryGetValue` on your dictionary when you have optional children. Of course there are trade-offs. I have seen some calls to `ToLookup()` generate considerably more memory usage than dictionaries, but I haven't looked into the root cause. Sometimes it's substantially less memory, faster, and overall just more ergonomic. Another thing that plays into your sorted span idea is whether or not you can have SQL Server do the sorting for you. SQL Server being the more-vertically scaling thing that it is, sometimes it makes more sense to have your .NET server do the sorting on its own, and other times you can put in place an index for your very specific query, give it an `ORDER BY` to ensure your C# code works regardless of that index's existence, but generally know that SQL Server likely won't need to do any additional work because its data will be presorted based on the index. Yet another thing that's top of mind to me because I was recently comparing statistics from different SQL Server Execution Plans is when SQL Server knows two data sets already share the same order (regardless of what the two are: a table, temp table, table variable, or table-valued parameter/data type) and it can leverage a Bitmap Create plan, do the whole Parallelism (Repartition Streams) steps beforehand, and Hash Match them together, then Gather Streams. I need to read more about that, but in theory, we could do that in C# too, yeah? What would that look like, and how would it compare to `Span<T>`? Could we combine the two? In previous videos of yours, I noticed you use `ToList()` after a grid reader call -- if you haven't already, look into `AsList()`; most of the time, unless you change settings, Dapper's grid reader is already going to have lists, and when you `ToList()` a List, you're just duplicating memory. And, unfortunately, `ToList()` isn't smart enough to look at the previous List's `Count`, so it's allocating an array, copying, running out of room, allocating a bigger array, copying, etc. `AsList()` just says "This is a list already so do nothing".
@aarondcmedia9585
@aarondcmedia9585 Ай бұрын
I never understand why people have videos with some part of the content at the beginning, with no context or discernible meaning. Was there a memo I missed? It happens nearly everywhere, including TV and makes no sense at all.
@JeffZuerlein
@JeffZuerlein Ай бұрын
Touché. Attention spans these days can be very short. Most people only watch the first 10 seconds of a video, so it’s hard to make good intros.
@aarondcmedia9585
@aarondcmedia9585 Ай бұрын
@@JeffZuerlein yeah I am clearly too old hahaa!
@chandez
@chandez Ай бұрын
Just one point. We don't always want to persist the entity and all its aggregates. For example, if we have a section for address changes. I've seen applications that use this technique to the extreme, persisting many aggregates unnecessarily.
@JeffZuerlein
@JeffZuerlein Ай бұрын
You bring up a point that bugs me with repositories that don’t have have access to change tracking. I don’t like to save data to the db when it hasn’t changed. It feels wasteful. EF Core ‘s best feature, to me, is change tracking. I have the tendency to look at an aggregate as a set of data that depends on each other. They have business rules that tie each other together. So if you had an address that could be changed and didn’t affect another entity, then I do think the address would be its own aggregate, with a repository of its own. I think it depends on the business rules.
@chandez
@chandez Ай бұрын
@@JeffZuerlein Exactly always depends on the context. 😃
@persiansayed
@persiansayed Ай бұрын
Great video! Please keep on making these informative videos. 😊
@JeffZuerlein
@JeffZuerlein Ай бұрын
More to come!
@o_glethorpe
@o_glethorpe Ай бұрын
Nice to see someone that is actually teaching something.
@JeffZuerlein
@JeffZuerlein Ай бұрын
Thank you!
@frankbanini8884
@frankbanini8884 Ай бұрын
Great video. I just subscribed to your channel.
@JeffZuerlein
@JeffZuerlein Ай бұрын
Awesome! Thank you!
@groenrechts5948
@groenrechts5948 Ай бұрын
And there goes yet another major selling point of C# into the garbage collector. Being a native C and C++ speaker this video makes me very happy, as I can now make even more fun of my C# colleagues. From many points of view this span<T> stuff is just hilarious. And, for the record, it is well explained in the video. Nothing wrong with that.
@mar_sze
@mar_sze Ай бұрын
Making fun of *any* programming language is for junior developers. Seniors use each to their strengths. Span allows for low-level optimizations in high-performance scenarios, without sacrificing all the benefits of C#, like type- and memory-safety. Span comes with a lot of safe-guards, while C++ is *always* low-level, giving you more "freedom" but also more risk.
@groenrechts5948
@groenrechts5948 Ай бұрын
@@mar_sze Question: Why should I not make fun of programming languages? They all have ridiculous features/notation/etc. Being allowed to use almost any date-type in an if-statement in C is hilarious, not to mention while loops intertwined with switch statements. Notation in C++ to remain backward compatible is sometimes ugly as hell and oftentimes super confusing for novices. Object oriented programming in Fortran90, what a joke it is. And so is C# filled with features that can be frowned upon. You see, as a senior developer I make fun of these things to remind people that programming languages are like a buffet where you should choose wisely what to eat and what not.
@JeffZuerlein
@JeffZuerlein Ай бұрын
There is plenty of code I like to make fun of…It has one author…Me. Over the years I’ve written plenty of programs that solved a problem, but suffered from many faults. It might look ill conceived, but that’s ok, it got the job done, and I got better because of it.
@JeffZuerlein
@JeffZuerlein Ай бұрын
Trade offs…It’s always a trade off. Everytime I interview someone for a position, I tell them I like working in a collegial team. I want to hear their ideas, and I want them to tell me when they think I’m wrong. At the end of the discussion, I expect we’ll both have learned something. There is a lot of value in perspective, and seeing the trade offs.
@groenrechts5948
@groenrechts5948 Ай бұрын
​@@JeffZuerlein Yes, trade offs are key, but oftentimes programmers have almost religious feelings about their 'holy' language. I used to have similar feelings decades ago, so I do understand, but I simply don't share this religious point of view anymore. And, for the record, the fact that I am a native C and C++ speaker does not imply anything. I am a native Dutch speaker as well, but I don't regard Dutch as the best language in the world. Not even close. But I can order a pizza in Dutch, and I can say Groningen and Scheveningen with the correct pronunciation. That's skill you see, very hard to master, but it is not an important skill. Junior programmers can hotly debate things in terms of 'better' and 'worse', whereas they should ask a bit more the 'what is it that actually matters' question. What are the true objectives of the project? On-time delivery? Performance? Maintainability? Flexibility? Being able to run on an FPGA? You can't have it all you know. Trade off it is, and I would like to know where the focus lies before I accept a position in my virtual job interview with you. This would be a fun discussion for sure, and we both might indeed learn something. Too bad I already have the best job in the world.
@mattserdar6599
@mattserdar6599 Ай бұрын
With privacy being a top concern, this is a great way to not fall in to the trap of using real customer data simply because "it's easy or we've always done it that way before". Well done Jeff!
@JeffZuerlein
@JeffZuerlein Ай бұрын
Great point! The last thing you want to do is leak sensitive data, or interact with real customers when you’re testing.
@kenbrady119
@kenbrady119 Ай бұрын
Turning our code into pretzels to safeguard memory access and housekeeping ... makes me want to return to C++ for the truly low-level work.
@JeffZuerlein
@JeffZuerlein Ай бұрын
I understand that feeling. I don’t think spans and memory are for every project. I see them as a special tool for a special situation. When perf matters, it’s nice to know you have the option.
@amrswalha
@amrswalha Ай бұрын
Nice video with great details, all the best.
@JeffZuerlein
@JeffZuerlein Ай бұрын
Thank you for the supportive comments! I'm really enjoying it.
Ай бұрын
Before this video I was thinking that I understand C#.... After this video I don't understand even heap and stack :D But thanks for sharing! Great video that pushes me (and pretty sure also other people) to learn new things!
Ай бұрын
But let me ask you.... In high performance application, like game development (like Unity) - it is good to know Spans/Memory of <T> ? Like when I need to calculate "millions" of data (position, rotation, etc...) with maximum performance - I must use these right ? (must.... Like.... I should to!)
@JeffZuerlein
@JeffZuerlein Ай бұрын
I haven’t written any games since I was using a C-64😂
@JeffZuerlein
@JeffZuerlein Ай бұрын
I can imagine them being out to use in a game.
@timeless-sg
@timeless-sg Ай бұрын
Great! Thanks. This channel deserves much more subscribers. Please keep up the good work!
@JeffZuerlein
@JeffZuerlein Ай бұрын
Much appreciated!
@ibrahimhussain3248
@ibrahimhussain3248 Ай бұрын
That's not possible with the FKs shown. Cannot insert an address without a person. The FK constraint will fail
@JeffZuerlein
@JeffZuerlein Ай бұрын
Good callout...I should have specified update statements.
@PerMadsen-tg1ik
@PerMadsen-tg1ik Ай бұрын
Great video - very useful for testing databases. As far as I can tell you don’t really utilize to Qty column is you script and the created data just get equally distributed. Do you have a sample of you script where you show the use of Qty?
@JeffZuerlein
@JeffZuerlein Ай бұрын
If anyone is interested in learning more about generating test data with a distribution of values, like this comment. That way I know how much interest there is in it.
@JeffZuerlein
@JeffZuerlein Ай бұрын
It works better with a small number of discrete values, like states. If 10% of the population lived in CA, you could create a new seed table with 1000 rows, and 100 would have the value CA. If WY had 1% of the population, it would get 10 rows. Then you can join the new seed table to the numbers table and generate values. If there are lots of discrete values like names of people....The volume of data gets too big, and it slows down.
@incubated
@incubated Ай бұрын
great overview. 👍for the dapper videos. thanks
@JeffZuerlein
@JeffZuerlein Ай бұрын
Glad you like them!
@2Fast4Mellow
@2Fast4Mellow Ай бұрын
Also to help spot performance problems with your queries, limit your database server to say 1 processor core and 1024MB ram. Another more complex option to to create a SMB share on another computer, limit the bandwidth between the database and SMB host and place the tempdb files on the SMB share. It is a bit similar to the network throttling option in your browser DevTools. Inefficient queries and other bottlenecks still standout more easily. To quickly change your DB settings save the change script to a .sql file. We also curated a large set of dogfeeding tables to populate application with loads of test data.
@JeffZuerlein
@JeffZuerlein Ай бұрын
You bring up a great point about the effect of network latency and bandwidth on application performance!
@cuongphung9163
@cuongphung9163 Ай бұрын
Thanks! I have leant a lot
@JeffZuerlein
@JeffZuerlein Ай бұрын
Glad to hear it!
@dsfgato
@dsfgato Ай бұрын
You’re a legend!! Your content is priceless! Thanks 🤘🏻
@JeffZuerlein
@JeffZuerlein Ай бұрын
That warms my heart. Glad I can help!
@samerelsahih
@samerelsahih Ай бұрын
Great video thank you ! If you're using EF, a good way would be in my opinion to use the UOW (Unit of work) pattern. It's easy to use, very straightforward and saves you from similar problems.
@JeffZuerlein
@JeffZuerlein Ай бұрын
Good point! If you're using SQL Client or Dapper, the UOW would probably have a SQL transaction. But with EF Core, I think that logic for order of updates would reside somewhere in the DB Context. Maybe I should read through that source code and find out how it chooses to order update statements. Thank you for the feedback!
@MrSupasonik
@MrSupasonik Ай бұрын
​@@JeffZuerleinThat's why I prefer Dapper; one has to invest so much time to understand how EF works under the hood, learning its abstractions and constraints (sure, you can skip this, but it will cause a mess in any serious cases). In contrast, with Dapper, it's much quicker and simpler, and you fully understand what will be sent to the SQL Server and how it will be processed there. Anyway, important (and concise, that's greatly appreciated) explanation. Keep up the good work!
@JeffZuerlein
@JeffZuerlein Ай бұрын
I really love Dapper. It gives you all the control you want, but I really want the change tracking that comes with EF. I can't tell you how many unneeded update statements get executed in Dapper because you can't tell if the domain entity mutated.
@thefastjojo
@thefastjojo Ай бұрын
Nice content Jeff! Your explanation helped me to test a bottleneck in a LINQ code I had in the ORM of my application.
@JeffZuerlein
@JeffZuerlein Ай бұрын
That's the best feedback I could get. Glad I was able to help you out!
@bhatsanket
@bhatsanket Ай бұрын
Really really like the tiitbits you are making... Nowadays because of things I am getting pushed away from programming but these really bring back memories... Ty! Please keep publishing
@JeffZuerlein
@JeffZuerlein Ай бұрын
That's so nice to hear! I've always loved the "internals" stuff, so it feels great to share with others.
@everyonesview
@everyonesview Ай бұрын
Appreciate you sharing this. Thanks. More of this, please?
@JeffZuerlein
@JeffZuerlein Ай бұрын
Well I appreciate the feedback, and yes I will be making more!
@MartinoBordin
@MartinoBordin Ай бұрын
The aggregate\aggregate root concept in DDD will naturally lead to this approach. Great video
@JeffZuerlein
@JeffZuerlein Ай бұрын
Thank you! I'm curious, do you generally use EF Core, Dapper, NHibernate, or SQL Client for data access?
@MartinoBordin
@MartinoBordin Ай бұрын
@@JeffZuerlein In my latest project I'm using EF Core. I believe it has everything nowadays to do proper data access
@AndrewBoudreau
@AndrewBoudreau Ай бұрын
​​@@MartinoBordinif you are using ef and have aggregates why not just use dbcontext.savechanges? I always felt like save on repository is making ef somuch less powerful. Thoughts?
@oldgraycoder
@oldgraycoder 3 ай бұрын
Good stuff sir. Keep up the good work.
@JeffZuerlein
@JeffZuerlein 3 ай бұрын
I appreciate hearing that, and I will.
@awright18
@awright18 3 ай бұрын
Great idea🎉🎉!
@JeffZuerlein
@JeffZuerlein 3 ай бұрын
Thank you! 😊
@nickcodes5430
@nickcodes5430 3 ай бұрын
Hi. Cool code. This is not relevant to the topic but since there are no arguments in the DateTime constructor (DateTime expected = new DateTime();) expected variable data is set to the default value making your Assert always to fail . Assert.That.SqlDatesAreEqual(result.Accepted.Value, expected); How are you getting data into "expected " variable? Thanks
@JeffZuerlein
@JeffZuerlein 3 ай бұрын
This is why I shouldn't post things on the internet while I'm going on a rant. :^) I fiddled with a real test to put the focus on the DateTime comparison. Normally what I do is to have properties in the test class to represent the expected values. An initialization function uses AutoFixture to populate those expected values and put them in the DB. That way when I test the repository's get method, I have something to compare the results to.
@nickcodes5430
@nickcodes5430 3 ай бұрын
@@JeffZuerlein Ah, that makes sense! Thank you, Sir!
@kudretkurt3832
@kudretkurt3832 4 ай бұрын
Great explanations!
@JeffZuerlein
@JeffZuerlein 3 ай бұрын
Thank you!
@jaiderariza1292
@jaiderariza1292 4 ай бұрын
thanks for this code... I think GetCustomerWithSortedSpanAndAdd() and GetCustomerWithSortedSpanAndSlice() are missing Product assignment to OrderItem
@JeffZuerlein
@JeffZuerlein 4 ай бұрын
Yes...You are correct. When I populate the aggregate with dapper, the product is assigned via a split. It this case I forgot to add that assignment. Thank you for pointing that out!
@qaisrani51
@qaisrani51 8 ай бұрын
Very informative.