Search code examples
asp.net-mvcasp.net-mvc-4asp.net-mvc-5

ASP MVC Controller And Static Variable


I have list of connection strings in web.config. And user has his "active" connection string from this list in cookie. This cookie can be chaged only at startup of app. So, in each request to controller i have to write:

Request.Cookies["activeServer"].Value

And pass it to repository. I think this is bad code, how can i do it better.

public ActionResult Index()
    {

        try
        {
            var m = new HomeRepository(Request.Cookies["activeServer"].Value);
            m.Tree = m.GetObjectsTree();
            return View(m);
        }
        catch(Exception ex)
        {
            ModelState.AddModelError("error", ex);
        }
        return View();
    }

    public ActionResult Lists()
    {
        try
        {
            var m = new HomeRepository(Request.Cookies["activeServer"].Value);
            return View(m.GetListsModel());
        }
        catch(Exception ex)
        {
            ModelState.AddModelError("error",ex);
        }
        return View();
    }

Solution

  • You use dependency injection in this case

    Define function:

    public string GetConnectionString()
    {
        //You should also check that cookie is no t null and value is not null...
        return Request.Cookies["activeServer"].Value;
    }
    

    Your controller constructor should get a repository as an argument:

    public class HomeController : Controller
    {
        public IHomeRepository HomeRepo {get; private set;}
        public HomeController (IHomeRepository repo)
        { 
           this.HomeRepo = repo;
        }
    }
    

    Define repository interface

    public interface IHomeRepository
    {
    }
    

    Define implementation of IHomeRepository

    public class HomeRepository : IHomeRepository
    {
        public Func<string> _getConnectionString;
    
        private string _connectionString;
    
        public HomeRepository( Func<string> getConnectionString)
        {
           this._getConnectionString = getConnectionString
        }
    
        public string ConnectionString {
            get{
    
               if(!this._connectionString.IsNullOrEmpty())
                  return this._connectionString;
    
               if(this._getConnectionString == null)
                   throw new ArgumentNullException();
    
               this._connectionString = this._getConnectionString();
               return  this._connectionString;
            }
        }
    }
    

    Use some dependency injection library to inject GetConnectionString function as a delegate to HomeRepository controller

    If you decide to use SimpleInjector library for example the injection will look like :

    container.RegisterSingle(GetConnectionString);
    container.Register<IHomeRepository, HomeRepository>();
    

    By applying this pattern you won't have to manually create your repositories in every action, you would be able to inject fake/mock repository object for testing