LINQ to SQL - where does your DataContext live? - asp.net

I'm using LINQ to SQL in a data access object library. The library is used in both web (web application/web service) and non-web (windows service) contexts. Initially, I stored the DataContext on the current HttpContext since it permitted me to manage a fairly small unit of work (one web request) and avoided global objects in a web app. Obviously, this doesn't work in a Windows Service.
Rick Strahl has a nice article on managing the DataContext's lifetime: http://www.west-wind.com/weblog/posts/246222.aspx. Unfortunately, I can't make up my mind on the best approach. A global DataContext doesn't work for reasons he mentions, a per-Thread DataContext seems complicated and potentially more trouble than it's worth, and a per-object instance seems fussy - you lose some elegance when you attach the DataContext used to create a DAO to that DAO so it can update or delete later - not to mention, there's something unpleasantly chicken-and-eggish about the relationship.
Does anyone have personal experience that suggests one approach is better than another? Or better yet, does anyone have a fourth or fifth approach I'm not seeing? Where is the best place to store and manage your DataContext?

The guidelines from the MSDN documentation on the DataContext class are what I would recommend following:
In general, a DataContext instance is
designed to last for one "unit of
work" however your application defines
that term. A DataContext is
lightweight and is not expensive to
create. A typical LINQ to SQL
application creates DataContext
instances at method scope or as a
member of short-lived classes that
represent a logical set of related
database operations.
Because DataContext is IDisposable, I find it easiest to create and use a DataContext in a using statement within one method, so it can be disposed of properly.
Also note that "any instance members are not guaranteed to be thread safe", so sharing one DataContext between multiple threads would be unwise.

Dependency Injection.
We prefer to keep our business layer ignorant of web vs non-web scenario's. Instead, business logic layer objects take a DataContext reference in their constructor which (explicitly) allows sharing the DataContext and (implicitly) allows sharing of the entity objects from query results as they are all from the same data context.
Also DataContexts implement IDisposable, so you really need to manage their lifetime. All our web forms have a base class, and part of that is a datacontext property (lazily created). That way everything on a page can share it, which is most often the case. The context is disposed of manually in the page's OnUnload() event.
You shouldn't mix linq entities from from different data contexts, and you typically get into trouble if you use the linq entities if the datacontext has been Dispose()'d of.

I'm using a per-thread context. It is tricky to setup, but it cleans up everything that needs to talk to the db.

I'm using httpcontext in web scenarios and thread context for everything else. We built a little framework so that the data context would be completely abstracted from the presentation/business tier.

Related

ASP.NET DbContext instance injection but not used - performance issue or not?

Latest approach says about injecting DbContext instance right to the MVC\WebAPI controller. It has a number of pros but I have one question which is not answered yet - performance of the DbContext instance creation which will not be used.
According to this question: What happens when i instantiate a class derived from EF DbContext? DbContext creation is not so cheap operation (both memory and CPU). And it's twice bad when:
Your action doesn't need the DbContext at all (so you have a mix actions which use and not use the DB)
Some logic (e.g. conditions) doesn't allow to access the DbContext (e.q. ModelState.IsValid). So action will return result BEFORE access to the DbContext instance.
So in both (an maybe some other cases) DI creates a scoped instance of the DbContext, wastes resources on it and then just collect it at the end of the request.
I didn't make any performance tests, just googled for some articles firsts. I don't say that it will be 100% lack of the performance. I just thought: "hey man, why have you created the instance of the object if I will not use it at all".
Why have you created the instance of the object if I will not use it
at all.
Mark Seemann said in his book Dependency Injection in .NET, "creating an object instance is something the .Net Framework does extremely fast. any performance bottleneck your application may have will appear in other place, so don't worry about it."
Please note that Dbcontext enables lazy loading by default. Just by instantiating it, it doesn't have much impact on the performance. So, I would not worry about Dbcontext.
However, if you have some custom classes doing heavy lifting inside constructor, then you might want to consider refactoring those.
If you really want to compare the performance, you could wrap those dependencies with Lazy, and see how much performance you gain. Does .net core dependency injection support Lazy.
You could register it as Lazy or you could do what I do and just inject IMyDbContextFactory and then you can call Create() that will return the DbContext when you actually need it (with its own pros/cons). If the constructor doesn't do anything, it won't be a huge hit, but keep in mind that the first time it gets newed up, it will hit the static constructor that goes through and does all the model validation. This hit only happens once, but it is a huge hit.

How to introduce application-wide context object?

I need to make several properties accessible from application's business layer. Those are some ids and common settings. Most of them are valid only through request-response lifespan.
This is a web application (ASP.NET Web Forms to be specific) with dependency injection set up.
Currently those properties are passed through method parameters directly to business layer's services. That works but is not very efficient since:
sometimes parameters' values need to be passed deeper obscuring the readability a bit
some properties should be lazy resolved, and this should be done only once per request
retrieving properties which are resolved by touching a database can be confusing for new developers (there is not unified way of doing this)
some services are constructed by a factory which enriches them with some config parameters
I was thinking about introducing an application context interface, with an implementation in the main project, which would be created on every request. It could be injected to the services directly making them parametrized automatically and independently (services won't need the factory anymore).
Is it how this problem should be tackled or maybe there are some other options?
One option I don't like here is that it might bond the main particle with business layer which is not a perfect example of The Clean Architecture.
Id say you solution is a very common one - inject an 'application context' into your classes. One thing I would be careful of though is making sure you are following the Integration Segregation Principle (from SOLID). Dont just start making all your classes expect an application context instance. Instead, design interfaces that split the application context up, and have your classes expect them as dependencies. Your application context will then need to implement all the interfaces.
This is the correct way to do things as it decouples your classes from implementation. Really your classes don't care if their dependency is from one giant application context, they just care about specific methods implemented by it. This will make your code more robust as you will reduce the risk of breaking something if you change the implementation of the application context later on.
Why don't you use some dependency injection container? Your global settings and parameters can be registered to it as pseudo-singletons and then you will be able to neatly request them from any point inside your application.

NHibernate, Sqlite, missing tables and IOC fun

I'm doing unit testing on a class library that uses NHibernate for persistence. NHibernate is using a Sqlite in-memory database for testing purposes. Under normal circumstances, it's easy to get StructureMap to kick out a session for me.
However, because I'm using the in-memory database to improve testing speed, I need to have a single session available for the duration of a test (because it blows the database away when I create a new one). And there is another wrinkle. The case that is currently burning me is testing a custom NHibernate-based ASP.NET membership provider. These are created apparently once per AppDomain, so I shouldn't inject the session into it, for obvious reasons.
Is there a way in structuremap to tell it to get rid of an instance of a particular type while still maintaining the bits that tell it how to instantiate that type? Really, if I could get away with it, I would just make it act like the HttpScoped object lifetime, but apparently I can only do that within the context of an Http request. Is there a straightforward way to manually control the lifetime of an object coming out of structuremap?
I apologize for the length of this and the possibility that it is a dumb question. I'm solo on this project, so I don't really have anyone to bounce ideas off of.
You could wrap the session in your own ISession implementation which delegates to a real session which lifetime you control. Then register your own ISession as instance.
I ended up making two constructors for my provider along with a private variable of type Func. By default, its value was set to my standard code for creating a session using StructureMap's ObjectFactory.
The overloaded constructor accepted as a parameter an object of type Func. That way, I can inject a strategy for creating an instance of that type if needed, but otherwise don't have to go through any extended effort. In the case of my test, I created the session in the NUnit setup method and destroyed it in the Teardown. I don't love this idea, but I don't currently hate it enough to rip it out....yet.
This got rid of the error I was experiencing in regard to the tables. However, it appears that NHibernate for some reason cannot write to an in-memory sqlite database under the conditions I created. I'm now working on testing to see if I can write to one in the file system. It isn't ideal, but it will be a good long while (I hope), before the performance of writing to disk really starts hurting.

Why use facade pattern in EJB?

I've read through this article trying to understand why you want a session bean in between the client and entity bean. Is it because by letting the client access entity bean directly you would let the client know exactly all about the database?
So by having middleman (the session bean) you would only let the client know part of the database by implementing the business logic in some certain way. So only part of the database which is relevant to the client is only visible. Possibly also increase the security.
Is the above statement true?
Avoiding tight coupling between the client & the business objects, increasing manageability.
Reducing fine-grained method invocations, leads to minimize method invocation calls over the network, providing coarse-grained access to clients.
Can have centralized security & transaction constraints.
Greater flexibility & ability to cope with changes.
Exposing only required & providing simpler interface to the clients, hiding the underlying complexity and inner details, interdependencies between business components.
The article you cite is COMPLETELY out of date. Check the date, it's from 2002.
There is no such thing anymore as an entity bean in EJB (they are currently retained for backwards compatibility, but are on the verge of being purged completely). Entity beans where awkward things; a model object (e.g. Person) that lives completely in the container and where access to every property of it (e.g. getName, getAge) required a remote container call.
In this time and age, we have JPA entities that are POJOs and contain only data. Don't confuse a JPA entity with this ancient EJB entity bean. They sound similar but are completely different things. JPA entities can be safely send to a (remote) client. If you are really concerned that the names used in your entity reveal your DB structure, you could use XML mapping files instead of annotations and use completely different names.
That said, session beans can still perfectly be used to implement the Facade pattern if that's needed. This pattern is indeed used to give clients a simplified and often restricted view of your system. It's just that the idea of using session beans as a Facade for entity beans is completely outdated.
It is to simplify the work of the client. The Facade presents a simple interface and hides the complexity of the model from the client. It also makes it possible for the model to change without affecting the client, as long as the facade does not change its interface.
It decouples application logic with the business logic.
So the actual data structures and implementation can change without breaking existing code utilizing the APIs.
Of course it hides the data structure from "unknown" applications if you expose your beans to external networks

ObjectContext in ASP.Net

I'm working with a project in ASP.Net using Webforms. I'm using Entity Framework to save data on Microsoft SQL.
My question is:
Is possible to use a Static class to keep the ObjectContext of EF live and put/get entities NOT saved inside the ObjectContext?
I want to create an Object, then added with AddObject on the ObjectContext, But NOT to do the Savechanges. All this in one webform. And then, in other webform, access to the ObjectContext and get the Object when added.
It is this possible?
My rules to using ObjectContext:
Do not use static context.
Do not share context.
You are trying to violate both rules. If you do that your application will have undeterministic behavior. Create new ObjectContext instance for each request. It is the same as openning new connection and starting new transaction in the request instead of sharing one connection and one transaction among all of them.
Further explanation also here. Also check linked question in right column and you will see what type of problems people have just because of violating one or both mentioned rules.
Also in web application it becames even more interesting because ObjectContext is not thread safe.
You could add it to the application items collection. See this blog post for syntax and such.
http://www.informit.com/articles/article.aspx?p=27315&seqNum=3
Generally, you don't want to. An ObjectContext is intended to be a unit of work, alive for a single set of related transactions. In an ASP.NET application, that generally corresponds to a single request.
If you must keep it alive for multiple requests, I wouldn't use either a static class, nor the application context. Instead, I'd recommend using the Cache, and then attaching the callbacks to it that let you ensure all your transactions are committed before it gets evicted, just in case.

Resources