8

I am currently working on including a new functionality for a Website.

I have a DbContext class which I created using EF6.

The website uses a Master Layout in which sublayouts are rendered depeding upon the page requested. I want to use Dependency Injection to access the DbContext in the Sublayouts. Generally, I would use a Controller to handle the calls, however, I want to skip that in this case.

Also, I want to keep the implementation flexible so that new DbContexts are added I will be able to use them easily.

I was thinking of creating an interface "IDbContext".

I will have the new interface(let's say "IRatings") implementing this interface.

Am I going about it the right way?

Any thoughts?

omkarshukla
  • 95
  • 1
  • 1
  • 6
  • Nothing special about `EF` really. Just keep in mind that `DbContext` is `IDisposable` so you have to manage lifetime somehow – Szer Feb 29 '16 at 11:26
  • 1
    @Szer Thanks for reminding me. Yes, I am aware of it. I just wanted to know how to do that? – omkarshukla Mar 01 '16 at 09:27
  • Here's how I did it with Castle Windsor, using an IDbContext interface. https://stackoverflow.com/questions/15654536/using-entity-framework-with-castle-windsor – Paul Taylor Jul 03 '18 at 14:14

1 Answers1

7

I am prefer SimpleInjector but it wont differ that much for any other IoC container.

More info here

Example for ASP.Net4:

// You'll need to include the following namespaces
using System.Web.Mvc;
using SimpleInjector;
using SimpleInjector.Integration.Web;
using SimpleInjector.Integration.Web.Mvc;

    // This is the Application_Start event from the Global.asax file.
    protected void Application_Start()
    {
        // Create the container as usual.
        var container = new Container();
        container.Options.DefaultScopedLifestyle = new WebRequestLifestyle();

        // Register your types, for instance:
        container.Register<IDbContext, DbContext>(Lifestyle.Scoped);

        // This is an extension method from the integration package.
        container.RegisterMvcControllers(Assembly.GetExecutingAssembly());

        // This is an extension method from the integration package as well.
        container.RegisterMvcIntegratedFilterProvider();

        container.Verify();

        DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container));
    }

Such registration will create DbContext per every WebRequest and close it for you. So you simply need inject IDbContext in your controller and use it as usual without using:

public class HomeController : Controller
{
    private readonly IDbContext _context;

    public HomeController(IDbContext context)
    {
        _context = context;
    }

    public ActionResult Index()
    {
        var data = _context.GetData();
        return View(data);
    }
}
Szer
  • 3,426
  • 3
  • 16
  • 36
  • Thanks @Szer! This is exactly what I did. We use a MVP framework. It gets initialized in Application_Start method. I created a new class RatingsContainerBuilder, which is derived from IInversionOfControlContainerBuilder, a IOC class which we use. In the overloaded method Build, i register the type with scope as InversionOfControlScope.PerHttpSessionScope. Does that seem okay? – omkarshukla Mar 01 '16 at 13:37
  • @omkarshukla yep, seems fine. Though I haven't work with such IoC container, but PerHttpSessionScope seems reasonable. It doesn't work or what? – Szer Mar 01 '16 at 13:40