Why You Don't Need To Abstract Away EF Core With Clean Architecture

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
in this video I'm going to show you how you can use EF core directly in the application layer of the clean architecture and what are the benefits and drawbacks of using this approach let's start off by actually creating the application project in our solution so I'm going to add a new project which is going to be a class library and I'm going to give it a name of application so let's go ahead and create this project it's going to be a Net 7 project and let's get rid of the default class that is added when we create a new project now I want to go ahead and install two nougat packages to our application project one is going to be mediator because I like using mediator for the use cases and the second is going to be EF core so let's go ahead and add these libraries so I want to install mediator we're going to add this Library the version 12.0.1 and let's add EF core I'm just going to add the default EF core library and not any of the providers like SQL server or postgres so let's add the EF core Library and let's see how we can Implement our first use case the use case that I'm going to implement is going to be creating the order and we're going to need a customer ID which we're going to pass from our API fetch the customer and if the customer exists then we create a new order so let's add a new feature folder in the application layer which I will call orders and the first feature that we're going to add is going to be the create feature so let's define the respective command and command Handler for this feature so I'm going to start off with the create order command I'm going to make the create order command into a record and all that we need on the create or recommend is going to be the customer ID I'm going to accept the raw value which is a guild from our API to the command and then we're going to map that into our strongly typed ID to be able to use this with mediator I need to decorated with the I request interface and I'm going to use the default one which has no response let's also add our create order command Handler and let's see how we can implement the Handler for this command so create order command Handler we're going to make the create order command Handler Shield and we have to implement the I request Handler interface and we have to specify the create order command so now I can implement the handle method and let's discuss how we're going to do this so we want to use EF core directly and I already have the application DB context in my processence project one approach can be directly moving this class into the application layer but I'm going to show you a slightly different approach I'm going to create a data folder and I'm going to Define an interface that is going to represent my DB context in the application layer so I'm going to call it I application DP context and on this interface of course it's not going to be a class it's going to be an interface I want it to be also public so on this interface I'm going to define the database sets that are going to represent the tables in my database so I know I have the customers and the orders entities that I'm going to work with in this use case so let's go ahead and add those I'm going to say DB set of customer and to be able to reference this I need to add a reference to The Domain project so I'm going to go ahead and do that we're going to give it a name of customers and we're going to give it a get and set property let's also do the same for the order and let's give it a name of orders with a get and set property so this is now the interface representing our application database context we're going to make our actual DB context implement this interface so I'm going to say hi application DB context I need to add a reference to the application project to be able to do this and let's implement the missing members so these are the customers and orders properties and we're going to just add these and now I can configure with dependency injection to get the application DB context instance when I inject the I application DB context interface so I'm going to actually be using this interface in the create order command Handler so I'm going to say private read-only I application DB context let's give it a name of context and let's just inject this from The Constructor and now implementing our use case becomes very simple and of course this has to be asynchronous so I first need to fetch the customer so I'm going to create the appropriate variable and I'm going to say await context customers we have a few options for how we can fetch the customer for example I can call the find async method which is going to return the customer with the primary key that I specify and the primary key is a customer ID which comes from our request so let me just format this then it's easier to see the customer could be null because it may not exist in the database so if that's the case let's simply check if the customer is null and I'm going to use the is now check here and just return from this method I don't have support for throwing validation exceptions at the moment so I'm just going to use this approach so The Next Step would be actually creating the order so to do that we're going to say VAR order we're going to call the static Factory method on the order entity which is going to create a new order instance based on the customer ID so I'm going to say customer ID and we get back a new order so now we can say context orders and we can add our new order what we need to do is persist changes to the database by calling our save changes method but if I try to access the save changes method you see that I don't have it defined on our interface so the simplest thing is just to go back to our interface and add the save changes method so the signature for the save changes method is a task returning an integer which represents the number of records that were changed and the name is save changes async because I want to use the asynchronous version it also accepts a cancellation token so I'm going to say cancellation token and give it a default value and if I go back to my application DB context you'll see that there is nothing to implement because the database context already implements the save changes method with this signature so now I can go back to my use case and I can say save changes async and pass send the cancellation token and this completes our create order command Handler so let's now discuss what are the implications of using EF cord directly in the application layer one direct benefit is speed and I hope you can see how fast I actually implemented this from scratch I just added an interface defined a few properties connected it to our actual DB context and I'm off to the races I can use our interface in place of the DB context and easily work with ef core one more benefit is I'm only depending on the I application DB context here which is very simple the DB context is going to implement the repository and unit of work patterns and we don't have to introduce a million dependencies in our use case it can't be all that good so what are the drawbacks of using this approach we are directly tied to using EF core in the application layer now this does allow us to switch SQL databases if we want to if we want to switch from a relational database to maybe a document database like ravendb then we'll have to do a complete rewrite of our application layer if we were using repositories instead then we would just have to re-implement the repositories to match our new database and we would leave the application layer intact another argument against this approach is that it breaks the clean architecture maybe maybe not I like to be pragmatic with my architecture and my implementation and using EF core is just so easy that I think it's worth the trade-offs I'm also going to show you how to configure the I application DB context with dependency injection so let's go ahead and add a class in our persistence project then I'm going to call dependency injection and we're going to add an extension method here on the I service collection interface to register rdb context and also register the I application DB context so I'm going to make this public static it's going to return the I service collection interface we're going to call it add persistence and it's going to be an extension method on the iservice collection interface I'm also going to add one more argument to this method which is going to be the I configuration interface so that we can access our connection string more easily so I'm going to add it right now and let's define the body of our method so the first thing I want to do is configure EF core I'm going to say Services add DB context and I'm going to specify our application DB context class then I want to say options and we're going to configure our database provider which is going to be postgraduate SQL in this case and I'm going to say use MPG SQL and we're going to say configuration get connection string and let's say that the connection string name is database so this configures our application DB context and now I want to configure the I application DB context interface so what we can do is we can say add scoped specify the I application DB context interface and we can specify the application DB context as the implementation in some.net versions this may not work as expected so the workaround usually is using the overload that gives you access to the service provider and you can say service provider get required service and specify the application DB context and this is going to work if the previous implementation does not let me know what you think about using EF core in the application layer of the clean architecture do you think it breaks the clean architecture or it's a good trade-off and you get a lot of benefits for doing that make sure to smash the like button and subscribe to my channel for more videos like this one and until next time stay awesome
Info
Channel: Milan Jovanović
Views: 40,916
Rating: undefined out of 5
Keywords: ef core, ef core 7, ef core 6, ef core code first approach, ef core migrations, ef core relationship, ef core code first, ef core vs dapper, ef core repository pattern, ef core clean architecture, ef core unit of work, ef core repository, ef core abstraction, ef core clean architecture abstraction, ef core performance, ef core flexiblity, ef core tutorial, ef core crash course, ef core configuration, ef core best practices, clean architecture, clean architecture ef core
Id: IGVRVO7KTss
Channel Id: undefined
Length: 10min 54sec (654 seconds)
Published: Tue Mar 21 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.