LZW
LZW

Reputation: 1045

ASP.NET MVC Controller recommendation for LINQ DataContext instantiation place

How should I instantiate the datacontext (entity fw) in a MVC Controller:

In WebForms I would use c), because b) would maintain the db object state across events, which is usually not what I want.

I actually never used a).

Upvotes: 1

Views: 1118

Answers (5)

mjhag
mjhag

Reputation: 1

Unless this is a very small application or has only a few users; or the lifetime of the application is short, I would never put the any data access "like" code in a UI layer. You just made a design decision that will impact the maintainability and testability of the application.

I like the idea of using a repository pattern with dependency injection - this has proven to work very well. In fact, the current application I work on processes over 11 billion web requests each month against 7 different database instances of MySQL using this pattern.

Another suggestion, implement a service/business layer under the UI. One of the responsibilities of this layer is to provide an API for business processing and database transactions. I usually implement the repository in the business layer, but it references and uses a data access layer component for the actual database-specific transactions. This way you have an abstraction of data access in your business layer - this is a good thing, because a long-lived application will many changes in data access. With this nice abstraction in place, you can use Entity Framework or any other database technology, like NoSQL. Also, using DI, interface/abstract classes allow you to inject the instance of the "repository" into the business component - this certainly improves the testability of your application: so fully unit test your application with a mocking framework (NUnit + Moq).

Hope this helps.

Upvotes: 0

jrummell
jrummell

Reputation: 43087

The recommended approach is to use a persistence agnostic data access pattern such as the Repository Pattern. The basic idea is to create controller specific interfaces that abstract away your data access.

public interface ICatalogRepository : IRepository
{
  Category GetCategory(int id);
  Product GetProduct(int id);

  void Add(Product product);

  IEnumerable<Category> Categories { get; }
  IEnumerable<Supplier> Suppliers { get; }
}

public class CatalogRepository : ICatalogRepository
{
  private YourDbContext _db;

  public CatalogRepository(YourDbContext db)
  {
     _db = db;
  }

  public Category GetCategory(int id)
  {
     return _db.Categories.Find(id);
  }
  /* ... */
}

Then you would use an instance of ICatalogRepository in your controller - it won't have any knowledge of Entity Framework. See Using the unit of work-per-request pattern in ASP.NET MVC for a complete example.

Upvotes: 0

Shyju
Shyju

Reputation: 218762

Have a private variable which is an object of your Repositary Interface and Instantiate it in your constructor. you can use that in all your action methods now

public class ItemsController : Controller
{
    private IRepositary repo;

    public ItemsController()
    {
        repo = new Repositary(new YourDBContext());
    }
    public ActionResult Edit(int id)
    {
      var item=repo.GetItemById(id);
      //if needed, map to your view model and return that to the view
     //  instead of model object to the view
      return View(item);
    }
}

Upvotes: 0

devlife
devlife

Reputation: 16145

I'd like to start by saying that I 100% agree with @jrummell in that the DbContext should be instantiated. However, if you aren't going to do that, I would use a private readonly field and provide two constructors:

public MyController() : this(new DbContext()) { }

public MyController(DbContext context)
{
   this._dbContext = context;
}

This way you can still inject a DbContext for testing.

Upvotes: 0

Parv Sharma
Parv Sharma

Reputation: 12705

you should probably make use of the repository pattern with dependency injection
passing in the context through the constructor
and with it you will have to use a toll like Unity to Inject the Context in the constructor

Upvotes: 2

Related Questions