Managing the Object Structure of an ObjectContext in ASP.NET

I am using the Entity Framework for an ASP.NET Web Forms application, and I am wondering how I should work with ObjectContext and this lifetime. For example, I have an InviteService class that manages invitations, such as creating and accepting invitations. The class itself is in another project / namespace from the web project. The InviteUsers() method creates Invite objects for the list of users, calls the repository to save them in the database, and sends each user a link to the invitation.

The method is called from Page when the user clicks the invitation button.

I would like to know how should I use an ObjectContext

  • Create a new ObjectContext on the page in each request, passing it as an argument to the constructor of the InviteService class, and then deleting it in the Render method.
  • The same as above, but instead of setting it through the constructor, passing it as a parameter for each method.
  • Create a separate ObjectContext in each method with a using block.

Option one seems better to me, based on Ladislav's answer here: Entity Framework and Connection Pooling But option 3 seems to be correct, since, as far as I know, no new connections to the database are happening due to the connection pool.

+4
source share
2 answers

It is not unusual to create one ObjectContext for each web request. I do this in my web applications. However, IMO, the page should not know anything about the ObjectContext .

Since you are already talking about introducing context into the service constructor, look at dependency injection (if you are not already using this). When you use the dependency injection container, you can let the container create this service for you and enter the context of the object in this container. The only thing your page should do is request a service from the container (ideally, you would even allow this service to be embedded in the constructor of this page, but this is not possible in web forms).

Your page will look like this:

 public class MyPage : Page { private readonly IMyService service; public MyPage() { this.service = Global.GetInstance<IMyService>(); } protected void Btn1_OnClick(object s, EventArgs e) { this.service.DoYourThing(this.TextBox1.Text); } } 

In the start path (Global.asax) of your application, you can configure the Injection Dependency infrastructure as follows:

 private static Container Container; public static T GetInstance<T>() where T : class { return container.GetInstance<T>(); } void Application_Start(object sender, EventArgs e) { var container = new Container(); string connectionString = ConfigurationManager .ConnectionStrings["MyCon"].ConnectionString; // Allow the container to resolve your context and // tell it to create a single instance per request. container.RegisterPerWebRequest<MyContext>(() => new MyContext(connectionString)); // Tell the container to return a new instance of // MyRealService every time a IMyService is requested. // When MyContext is a constructor argument, it will // be injected into MyRealService. container.Register<IMyService, MyRealService>(); Container = container; } 

In these examples, I used the Simple Injector injection container, although any DI container will do. RegisterPerWebRequest not part of the main library, but is available as an extension package (NuGet) . The package ensures that your ObjectContext will be deleted when the web request is complete.

This may seem complicated at first, but on this web page you don’t have to worry about any details about creating and deleting an ObjectContext .

Also, put the logic that runs the use case in one class: command. Let a team (or system) ensure the atomicity of this operation. Do not let the page be responsible for this and do not execute it at the end of the request, because at this moment you will not know whether it is normal to even make a call. No, let the team handle this on their own. Here is an article on writing business teams .

This tip applies to ASP.NET MVC, although you should not call Global.GetInstance<IMyService>() inside the Controller constructor, but just use the constructor installation (since MVC has great support for this) and use the MVC3 integration package .

Also consider fooobar.com/questions/20350 / ... , which talks about choosing between an IObjectContextFactory or having an ObjectContext for each request.

+6
source

1 is the best solution. In the world, NHibernate is called a session per request.

You can create an ObjectContext in BeginRequest and flash / commit it in EndRequest.

1 is better than 3 because you start working with ORM (Entity Framework in your case) when a request arrives. Then you add the object to the tree, modify the class, delete, etc. During the life cycle of ALL.

Only during EndRequest do you make ALL of your changes in only one batch.

EDIT: as @Steven says, it is not ideal for eliminating an exception during commit.

So, suppose you have a web form with a save button:

  • create an ObjectContext during BeginRequest
  • calling commit on the Save Command command
  • just close / remove ObjectContext during EndRequest
+2
source

Source: https://habr.com/ru/post/1391848/


All Articles