DbContext per HTTP Request But Avoid Dependency on HttpContext in Data Layer - asp.net

I've been thinking of how I could use one instance of a DbContext per HttpRequest in a layered application. One of the solutions I came up with would be to create an HttpModule that would initialize an instance of the context in HttpContext.Current.Items in the BeginRequest event handler and then dispose it in the EndRequest event handler.
The approach above poses a problem though: I need to reference System.Web in my data layer and business layer in order to get a hold of the stored DbContext instance. This is probably okay but I prefer to avoid going that route. What if I wanted to reference and use my data layer and business layers from a non-web application?
Any ideas?

You can use dependency injection. Simply create interface IContextHolder with method to get a context and inject the instance into your lower layer from the web application. The implementation of this interface will be different for different types of applications - it will wrap the access to the real storage for your context instance.

One of the simplest solutions would be to wrap the access to the data context in a static property in a facade/gateway class.
This way, in a web application, the property could access the HttpContext.Current.Items and store the context there. On the other hand, if the http context is missing, you could implement any other lifetime management policy for a non-web application.
public static TheDbContext Current {
get {
if ( HttpContext.Current != null ) {
// lifetime management for a web app
// e.g. with the Items container
}
else {
// lifetime management for a non-web app
}
}
}
The facade itself doesn't have to be a part of the data layer, you don't then reference System.Web in a data layer.

Related

Is it possible to create a global context available throughout the web application when i receive a message from Azure Service Bus?

I have a web api application which subscribes to a topic in azure service bus during startup.
When I receive a message from service bus, is it possible to establish a context similar to HttpContext that is available across the application methods?
There's not enough here to give you any exact direction, but in general, this just involves scopes. If whatever is listening for messages is has a "scoped" lifetime, then you can inject your context directly. If, as is more likely, it has a singleton lifetime, then you must instead inject IServiceProvider and retrieve your context via:
using (var scope = provider.CreateScope())
{
var context = scope.ServiceProvider.GetRequiredService<MyContext>();
// do something with context
}
You can only use the context within the scope, so do not try to do something like store it in an instance variable or something.

Get same instance of a component registered with Autofac as InstancePerLifetimeScope in Global.asax methods as is injected into a controllers?

I have a situation where I need to manually instantiate some objects in Application_BeginRequest that are dependent on some of the same components that I've registered with Autofac. I'd like to use the same instances of components that I've registered with Autofac with InstancePerLifetimeScope for injection into my MVC and WebAPI controllers. My config for both MVC and Web API works as expected, and an example of a component registration looks like so:
builder.Register(c => new MyDbContext()).AsSelf().InstancePerLifetimeScope();
Now I want to use that same instance in the class I'm instantiating in Application_BeginRequest. I've tried the following methods:
//Tried with MVC controllers
DependencyResolver.Current.GetService<MyDbContext>()));
AutofacDependencyResolver.Current.ApplicationContainer.Resolve<MyDbContext>()));
AutofacDependencyResolver.Current.RequestLifetimeScope.Resolve<MyDbContext>()));
//Tried with Web API controllers
GlobalConfiguration.Configuration.DependencyResolver.GetService(typeof(MyDbContext))
But none give me what I'm looking for, even at later points in the request lifecylce (ie, beyond BeginRequest). As an aside, I need this to work with the Web API configuration, but I tried the first 3 methods just to see if I could get any of the resolved instances to match up with what Autofac is injecting.
I have what I believe is a decent understanding of lifetime scopes in Autofac and my assumption is that the instances that are being resolved for my application's controllers are in a child scope that the none of the above 4 methods are pointed towards, but it's fuzzy to me what each of the above methods is trying to do in regard to which scope they are looking at and how they decide. What's even fuzzier is what lifetime scopes Autofac is automatically creating for the components that are ultimately injected into my controllers and when they're created.
Clarification on the points above would be a big bonus, but my primary question here is how do I get Autofac to hand me the same instances of registered components in Global.asax that it resolves for Web API and MVC controllers?
If you read up on this subject, you'll notice that folks mention that in most circumstances for a web application, InstancePerLifetimeScope and InstancePerRequest can be used interchangeably. What they don't mention are the exceptions where these two registrations behave differently. Gerrod has an excellent article on lifetime scopes inside of ASP.NET MVC/Web API applications and how they work in which he elaborates on this piece of info that most omit. Understanding this difference is crucial to this scenario, and his article cleared up any misunderstandings I had in regards to InstancePerLifetimeScope registration in relation to ASP.NET applications. It also made me realize that, because I need to share instances of resolved components across my MVC/Web API controllers and within the global.asax, InstancePerLifetimeScope is no longer a suitable means of registration for this application- I now need to use InstancePerRequest.
As per the docs, InstancePerRequest actually uses InstancePerMatchingLifetimeScope under the hood. What I need is a reference to the child scope that is tagged with "AutofacWebRequest" that lives under the root scope. This is the scope that both my MVC and Web API controllers resolve their dependencies from, since they both use the same tag. So how do I get a reference to that particular scope? This was my solution, and I'd love to know if there's a better way to do it.
First off, I need to change my registration from
builder.Register(c => new MyDbContext()).AsSelf().InstancePerLifetimeScope();
to
builder.Register(c => new MyDbContext()).AsSelf().InstancePerRequest();
Now, after I've built my container I have the following method:
private void SetDependencyResolversForMvcAndWebApi(ILifetimeScope container)
{
container.ChildLifetimeScopeBeginning += CaptureRequestLifetimeScope;
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
GlobalConfiguration.Configuration.DependencyResolver = new AutofacWebApiDependencyResolver(container);
}
The only part that wasn't there before is the event subscription. Everytime my container creates a child scope, my event handler gets called. The event handler looks like this:
private void CaptureRequestLifetimeScope(object sender, LifetimeScopeBeginningEventArgs args)
{
if (args.LifetimeScope.Tag == MatchingScopeLifetimeTags.RequestLifetimeScopeTag)
{
//Get the ILifetimeScope created for components registered with InstancePerRequest
var requestScope = args.LifetimeScope;
//This is the same DbContext instance that will be injected into
//my WebAPI and MVC controllers
var context = requestScope.Resolve<MyDbContext>();
//do the rest of my stuff
}
}
I've tested this by holding onto a reference of the resolved DbContext that's resolved within the CaptureRequestLifetimeScope event handler and comparing it to the DbContext instances that are injected into my Web API and MVC controllers, and they are indeed pointing to the same object.
Well, I think you should try changing .InstancePerLifetimeScope() into .InstancePerRequest();
As Autofac says about InstancePerLifetimeScope:
When you resolve the instance per lifetime scope component, you get a single instance per nested scope (e.g., per unit of work).
So when you do Resolve<MyDbContext>() you are probably doing it in a different Lifetime scope than you controller (I guess it's because you're doing an explicit resolution); that's why you're getting a diffent instance.
InstancePerRequest instead:
Some application types naturally lend themselves to “request” type semantics, for example ASP.NET web forms and MVC applications. In these application types, it’s helpful to have the ability to have a sort of “singleton per request.”
The begin phase of your request is already in the request phase, so you shoud get the same instance there and inside your controllers.
Instance per request builds on top of instance per matching lifetime scope by providing a well-known lifetime scope tag, a registration convenience method, and integration for common application types.
Based on this, probably, you can also go for the .InstancePerMatchingLifetimeScope("myrequest"), but you will have to manually instanciate a Lifetime scope everywhere like this using(var scope1 = container.BeginLifetimeScope("myrequest")); I think is not so practical.
Obviously I suppose you will not use those elements outside of the request scope, or you will get an exception. In that case, you are forced to the MatchingLifetimeScope.
If you need more details, the Autofac guide is extremely clear.
DependencyResolver.Current.GetService<MyDbContext>()));
AutofacDependencyResolver.Current.RequestLifetimeScope.Resolve<MyDbContext>()));
are same. They get current request lifetime scope. If you resolve some instance here, it shares it with cotrollers. (In this stiuation, instance per request and instance per lifetime will be same. Because their lifetime is same).
AutofacDependencyResolver.Current.ApplicationContainer.Resolve<MyDbContext>()));
This wil be resolved from root container. That's why it will create another instance for request lifetime scope. This will not be shared. And this will live in root container. (If you have per request instance, this will give error).
I have tested first one. It shares instance resolved in Application_BeginRequest with mvc controllers but not with Api controllers.
Then I tried to get GlobalConfiguration.Configuration.DependencyResolver.GetRequestLifetimeScope() in Application_BeginRequest it returns null.
I think, if it's api request, Autofac doesn't start request lifetime yet in Application_BeginRequest (May be it's related .net).
So if it's api request and if we can't reach autofac request life time. I don't know how to share this instance with mvc and api controllers which is resolved in Application_BeginRequest.
May be Travis can make it clear.

EF6 (code first), MVC, Unity, and a service layer without a repository

My application is using SQL Server 2012, EF6, MVC and Web API.
It's also using a repository and assorted files such as:
DatabaseFactory.cs
Disposable.cs
IDatabaseFactory.cs
IRepository.cs
IUnitOfWork.cs
RepositoryBase.cs
UnitOfWork.cs
We already use a service layer between our controllers and the repository
for some complicated business logic. We have no plans EVER to change to a different database and it has been pointed
out to me that the recent thinking is that EF6 is a repository so why build
another repository on top of it and why have all of the files I have above.
I am starting to think this is a sensible approach.
Does anyone know of any examples out there that implement EF6 without a
repository, with a service layer. My search on the web has revealed many
complex code examples that seem over complicated for no reason at all.
My problem is also when using a Service Layer then where do I put:
context = new EFDbContext()
In the controller, the service layer or both ? I read that I can do this with dependancy injection. I already use Unity as an IOC but I don't know how I can do this.
Entity Framework IS already a Unit of Work pattern implementation as well as a generic repository implementation (DbContext is the UoW and DbSet is the Generic Repository). And I agree that it's way overkill in most apps to engineer another UoW or Generic Repository on top of them (besides, GenericRepsitory is considered to be an anti-pattern by some).
A Service layer can act as a concrete repository, which has a lot of benefits of encapsulating data logic that is specific to your business needs. If using this, then there is little need to build a repository on top of it (unless you want to be able to change your backend service technology, say from WCF to WebApi or whatever..)
I would put all your data access in your service layer. Don't do data access in your controller. That's leaking your data layer into your UI layer, and that's just poor design. It violates many of the core SOLID concepts.
But you do NOT need an additional UnitOfWork, or other layers beyond that in most cases, unless your apps are very complex and intended to work in multiple environments...
Setting up Unity for ASP.NET MVC and WebAPI is quite easy if you install and add the Unity.Mvc* and Unity.WebAPI* Nuget packages to your project. (The * is a version number, like 3 or 4 or 5. Look for the appropriate versions for your project. Here are for example the links to the Unity.Mvc 5 package and to the Untity.WebAPI 5 package.)
The usage of these packages is explained in this blog post.
The building blocks are roughly like so:
You build a unity container and register all your dependencies there, especially the EF context:
private static IUnityContainer BuildContainer()
{
var container = new UnityContainer();
container.RegisterType<MyContext>(new HierarchicalLifetimeManager());
container.RegisterType<IOrderService, OrderService>();
container.RegisterType<ICustomerService, CustomerService>();
container.RegisterType<IEmailMessenger, EmailMessenger>();
// etc., etc.
return container;
}
MyContext is your derived DbContext class. Registering the context with the HierarchicalLifetimeManager is very important because it will ensure that a new context per web request will be instantiated and disposed by the container at the end of each request.
If you don't have interfaces for your services but just concrete classes you can remove the lines above that register the interfaces. If a service needs to be injected into a controller Unity will just create an instance of your concrete service class.
Once you have built the container you can register it as dependency resolver for MVC and WebAPI in Application_Start in global.asax:
protected void Application_Start()
{
var container = ...BuildContainer();
// MVC
DependencyResolver.SetResolver(
new Unity.MvcX.UnityDependencyResolver(container));
// WebAPI
GlobalConfiguration.Configuration.DependencyResolver =
new Unity.WebApiX.UnityDependencyResolver(container);
}
Once the DependencyResolvers are set the framework is able to instantiate controllers that take parameters in their constructor if the parameters can be resolved with the registered types. For example, you can create a CustomerController now that gets a CustomerService and an EmailMessenger injected:
public class CustomerController : Controller
{
private readonly ICustomerService _customerService;
private readonly IEmailMessenger _emailMessenger;
public CustomerController(
ICustomerService customerService,
IEmailMessenger emailMessenger)
{
_customerService = customerService;
_emailMessenger = emailMessenger;
}
// now you can interact with _customerService and _emailMessenger
// in your controller actions
}
The same applies to derived ApiControllers for WebAPI.
The services can take a dependency on the context instance to interact with Entity Framework, like so:
public class CustomerService // : ICustomerService
{
private readonly MyContext _myContext;
public CustomerService(MyContext myContext)
{
_myContext = myContext;
}
// now you can interact with _myContext in your service methods
}
When the MVC/WebAPI framework instantiates a controller it will inject the registered service instances and resolve their own dependencies as well, i.e. inject the registered context into the service constructor. All services you will inject into the controllers will receive the same context instance during a single request.
With this setup you usually don't need a context = new MyContext() nor a context.Dispose() as the IOC container will manage the context lifetime.
If you aren't using a repository then I assume you would have some place to write your logic/processing that your service operation would use. I would create a new instance of the Context in that logic/process class method and use its methods directly. Finally, dispose it off right after its use probably under a "using".
The processing method would eventually transform the returned/processed data into a data/message contract which the service returns to the controller.
Keep the data logic completely separate from Controller. Also keep the view model separate from data contract.
If you move ahead with this architecture, you are going to be tightly coupling the Entity Framework with either your service or your controller. The repository abstraction gives you a couple things:
1) You are able to easily swap out data access technologies in the future
2) You are able to mock out your data store, allowing you to easily unit test your data access code
You are wondering where to put your EF context. One of the benefits of using the Entity Framework is that all operations on it are enrolled into a transaction. You need to ensure that any data access code uses the same context to enjoy this benefit.
The design pattern that solves that problem is the Unit of Work pattern, which by the looks of things, you are already using. I strongly recommend continuing to use it. Otherwise, you will need to initialize your context in your controller, pass it to your service, which will need to pass it to any other service it interacts with.
Looking at the objects you have listed, it appears to be a considerate attempt to build this app with enterprise architectural best practices. While abstractions do introduce complexity, there is no doubting the benefit they provide.

Removing singletons from large .NET codebase

The context:
(Note: in the following I am using "project" to refer to a collection of software deliverables, intended for a single customer or a specific market. I am not referring to "project" as it is used in Visual Studio to refer to a configuration that builds a single EXE or DLL, within a solution.)
We have a sizable system that consists of three layers:
A layer containing code that is shared across projects
A layer containing code that is shared across different applications within a project
A layer containing code that is specific to a particular application or website within a project.
The first two layers are built into DLL assemblies. The top layer is an assortment of EXEs and/or .aspx web applications.
IIRC, we have a number of different projects that use this pattern. All four share layer 1 (though often in slightly different versions, as managed by the VCS). Each of them has its own layer 2. Each of them has its own set of deliverables, which can range from a website, or a website and a background service, to our largest and most complex (and the bread-and-butter of our business) which consists of something like five independent web applications, 20+ console applications/background services, three or four independent web services, half-a-dozen desktop GUI apps, etc.
It's been our intent to push as much code into levels 1 and 2 as possible, to avoid duplicating logic in the top layers. We've pretty much accomplished that.
Each of layers 1 and 2 produce three deliverables, a DLL containing the code that is not web-related, a DLL containing the code that is web-related, and a DLL containing unit tests.
The problem:
The lower levels were written to make extensive use of singletons.
The non-web DLL in layer 1 contains classes to handle INI files, logging, a custom-built obect-relational mapper, which handles database connections, etc. All of these used singletons.
And when we started building things on the web, all of those singletons became a problem. Different users would hit the website, log in, and start doing different things. They'd do something that generated a query, which would result in a call into the singleton ORM to get a new database connection, which would access the singleton configuration object to get the connection string, and then the connection would be asked to perform a query. And in the query the connection would access the singleton logger to log the SQL statement that was generated, and the logger would access the singleton configuration object to get the current username, so as to include it in the log, and if someone else had logged in in the meantime that singleton configuration object would have a different current user. It was a mess.
So what what we did, when we started writing web applications using this code base was to create a singleton factory class, that was itself a singleton. Every one of the other singletons had a public static instance() method that had been calling a private constructor. Instead, the public static instance() method obtained a reference to the singleton factory object, then called a method on that to get a reference to the single instance of the class in question.
In other words, instead of having a dozen classes that each maintained its own private static reference, we now had a single class that maintained a single static reference, and the object that it maintained a reference to contained a dozen references to the other, formerly singleton classes.
Now we had only one singleton to deal with. And in its public static instance() method, we added some web-specific logic. If we had an HTTPContext and that context had an instance of the factory in its session, we'd return the instance from the session. If we had an HTTPContext, and it didn't have a factory in its session, we'd construct a new factory and store it in the session, and then return it. If we had no HTTPContext, we'd just construct a new factory and return it.
The code for this was placed in classes we derived from Page, WebControl, and MasterPage, and then we used our classes in our higher-level code.
This worked fine, for .aspx web applications, where users logged in and maintained session. It worked fine for .asmx web services running within those web applications. But it has real limits.
In particular, it won't work in situations where there is no session. We're feeling pressure to provide websites that serve a larger user base - that might have tens or hundreds of thousands of users hitting them dynamically. Up to now our users have been pretty typical desktop business users. They log into our websites, and stay in them much of the day, using our web apps as an alternative to a desktop app. A given customer might have as many as six users who might use our websites, and while we have a thousand or more customers, combined they don't make for all that heavy a load. But our current architecture will not scale to that.
We're also running into situations where ASP.NET MVC would be a better fit for building the web UI than .aspx web forms. And we're exploring building mobile apps that would be communicating with stand-alone WFC web services. And while in both of these, it looks like it's possible to run them in an environment that has a session, it looks to limit their flexibility and performance fairly severely.
So, we're really looking at ways to eliminate these singletons.
What I'd really like:
I'm trying to envision a series of refactors, that would eventually lead to a better-structured, more flexible architecture. I could easily see the advantages of an IoC framework, in our situation.
But here's the thing - from what I've seen of IoC frameworks, they need their dependencies provided to them externally via constructor parameters. My logger class, for example, needs an instance of my config class, from which to obtain the current user. Currently, it is using the public static instance() method on the config class to obtain it. To use an IoC framework, I'd need to pass it as a constructor.
In other words, from where I sit, the first, and unavoidable task, is to change every class that uses any of these singletons so as to take the singleton factory as a constructor parameter. And that's a huge amount of work.
As an example, I just spent the afternoon doing exactly that, in the level 1 libraries, to see just how much work it is. I ended up changing over 1300 lines of code. The level 2 libraries will be worse.
So, are there any alternatives?
Typically, you should try to wrap the contextual information into its own instance and provide a static accessor method to refer to it. For example, consider HttpContext and its available every where in web application via HttpContext.Current.
You should try to devise something similar so that instead of returning singleton instance, you would return the instance from the current context. That way, you need to not change your consumer code that refers to these static methods (e.g. Logger.Instance()).
I generally roll-up information such as logger, current user, configuration, security permissions into application context (can be more than one class if need arises). The AppContext.Current static method returns the current context. The method implementation goes something like
public interface IContextStorage
{
// Gets the stored context
AppContext Get();
// Stores the context, context can be null
void Set(AppContext context);
}
public class AppContext
{
private static IContextStorage _storageProvider, _defaultStorageProvider;
public static AppContext Current
{
get
{
var value = _storageProvider.Get();
// If context is not available in storage then lookup
// using default provider for worker (threadpool) therads.
if (null == value && _storageProvider != _defaultStorageProvider
&& Thread.CurrentThread.IsThreadPoolThread)
{
value = _defaultStorageProvider.Get();
}
return value;
}
}
...
}
IContextStorage implementations are application specific. The static variables _storageProvider gets injected at the application start-up time while _defaultStorageProvider is a simple implementation that looks into current call context.
App Context creation happens in multiple stages - for example, a global information such as configuration gets read and cached at application start-up while specific information such as user & security gets formed at authentication stage. Once all info is available, the actual instance is created and stored into the app specific storage location. For example, desktop application will use a singleton instance while web application can probably store the instance into the session state. For web application, you may have logic at start of each request to ensure that the context is initialized.
For a scalable web applications, you can have a storage provider that will store the context instance into the cache and if not present in the cache then re-built it.
I'd recommend starting by implementing "Poor Man's DI" pattern. This is where you define two constructors in your classes, one that accepts an instance of the dependencies (IoC), and another default constructor that new's them up (or calls a singleton).
This way you can introduce IoC incrementally, and still have everything else work using the default constructors. Eventually when you have IoC being used in most places you can start to remove the default constructors (and the singletons).
public class Foo {
public Foo(ILogger log, IConfig config) {
_logger = log;
_config = config;
}
public Foo() : this(Logger.Instance(), Config.Instance()) {}
}

Getting ApplicationState in asp.net without HttpContext

I got a webapp that stores a config object in ApplicationState.
This object contains the connection string to the database among other things.
Sometimes i start a async thread to do a few longer running tasks, like sending emails and updating the database.
However since this thread don't have a HttpContext i can't get at the config object.
I know this design that everything depends on HttpContext is bad, but thats too late to change now.
Looking at reflector i see that the HttpContext class just uses a static internal class to get the ApplicationState. Is there any other way to get at it?
All those internal classes in .net are really annoying.
Just pass whatever you like to your thread when you start it. Use a ParameterizedThreadStart delegate to start it instead of just a ThreadStart delegate. You could either pass it HttpContext.Current, or else bundle together the information you want your thread to have, and pass it.
If you really need access to Application State (or similar) from async handlers you should modify your HttpApplication subclass (e.g. Global.asax) to store the Application State instance (this.Application) to a static property during Application_Start:
public static HttpApplicationStateWrapper State { get; private set; }
protected void Application_Start()
{
State = new HttpApplicationStateWrapper(this.Application);
}
It would be more appropriate to use a DI framework to register this instance, but if you have one available you could probably avoid the use of Application State altogether for storing config. Further, there is a configuration framework in .NET that directly addresses this need and provides the ability to read configuration from anywhere.

Resources