BrunoRamalho
BrunoRamalho

Reputation: 1786

ASP.NET MVC Global DB

I'm trying to set the variable DB as global and use anywhere. My problem is that I'm initialising twice the db. In the base controller and in atributes. ie:

public class SettingsAttribute : ActionFilterAttribute {
  public ApplicationDbContext db = new ApplicationDbContext();
  public override void OnActionExecuting(ActionExecutingContext filterContext) {
    ...
}

and

[Settings]
public class BaseController : Controller {
  public ApplicationDbContext db = new ApplicationDbContext();
  protected override IAsyncResult BeginExecuteCore(AsyncCallback callback, object state) {
    ...
}

I would like to create the var db just once, and access anywhere in the project. How ca I do this?

Upvotes: 0

Views: 683

Answers (3)

David Ferenczy Rogožan
David Ferenczy Rogožan

Reputation: 25401

Consider using of Dependency Injection pattern. For .NET there is for example Unity container, which implements a lightweight, extensible dependency injection container. Check the List of dependency injection containers for .NET, but it's quite old.

In general, Dependency injection is called Inversion of Control (IoC). That means, your classes, which are using for example your DB class, don't need to be dependent on a specific DB class. Instead, they just require a specific interface. DB class implementing this interface is injected from the outside and your class is decoupled from a specific implementation of DB class.

Some places to start with:

Upvotes: 3

IndieTech Solutions
IndieTech Solutions

Reputation: 2541

Best practice in this situation and (similar situations) is to implement a DI/IoC pattern , as @Dawid-Ferenczy mentioned in his answer. if you never worked with it before , it's a little abstract at the beginning but it's very useful in the long run , especially if your objects got complicated. You can search online for articles to learn more about the pattern itself.

@Dawid-Ferenczy mentioned the Unity container, but it's not limited to that , you can use any container you would like (Or even create your own if you need to ). I personally use Ninject as it has a has a lot of support documentation and i found it easy to implement.

In your case (DB context) i would use Ninject and DI/IoC as follow:

1- Declare an interface for your DB Context DAL:

  public interface IModelDBContext
    {
//Your methods should go here
    }
  1. Your concrete class:

    public class ModelDBContext : DbContext,IModelDBContext { //Your methods and other stuff here }


Container part

(Ninject in my case , but you can use any other container)

public class NinjectDependencyResolver : IDependencyResolver
    {
    //Bunch of initialization and methods 
    Check out this : [Using ninject in MVC][2].
    //Binding piece (Very important)
     private void AddBindings()
            {
                //Context DB Binding
                kernel.Bind<IModelDBContext>().To<ModelDBContext>();
                //Other binding
            }
    }

Implementation part:

This is the fun and exciting part. anywhere in your application , if you need to implement your specific DB context you inject it with the constructor and it will be available for you to use:

In your case it will be something like this:

    Public YourConcreteClass
    {
    Private IModelDBContext ModelDB; //Initiate an instance that you will use .


//DI by constructor
public YourConcreteClass(IModelDBContext mDB)
        {
    ModelDB=mDB;

        }
//in the rest of your code you call ModelDB that has access to all of the methods and attributes you might need

    }

Upvotes: 1

JoaoRibeiro
JoaoRibeiro

Reputation: 928

What about putting it in another class (an Helper, for instance), and access it like this:

private ApplicationDbContext db = null;
public ApplicationDbContext Db {
    get {
        if (db == null)
            db = new ApplicationDbContext();
        return db;
    }
}

Upvotes: 2

Related Questions