blgrnboy
blgrnboy

Reputation: 5157

Assign some values from MVC Application_Start to a static class

I have a requirement to show some of that database information in the layout view of my MVC application.

I was thinking that if I did this in the Application_Start() method, and assigned to a static class with a static value, the view would be able to access those variables and display them...but them show up blank.

Here is the Application_Start():

NWatchEntityApplication nWatchApp;

protected void Application_Start()
{
    var assemblies = BuildManager.GetReferencedAssemblies().Cast<Assembly>();
    AreaRegistration.RegisterAllAreas();
    GlobalConfiguration.Configure(WebApiConfig.Register);
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    BundleConfig.RegisterBundles(BundleTable.Bundles);

    nWatchApp = new NWatchEntityApplication(GetNWatchConfig());
    SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(nWatchApp.Configuration.NWatchDatabase);
    Infrastructure.ApplicationInfo.NWatchDatabaseCatalog = builder.InitialCatalog;
    Infrastructure.ApplicationInfo.NWatchDatabaseServer = builder.DataSource;

    var context = nWatchApp.GetDbContext();
    builder = new SqlConnectionStringBuilder(context.DatabaseConnectionString);
    Infrastructure.ApplicationInfo.EntityDatabaseCatalog = builder.InitialCatalog;
    Infrastructure.ApplicationInfo.EntityDatabaseServer = builder.DataSource;

    var webApiContainer = new Container();
    webApiContainer.Options.DefaultScopedLifestyle = new WebApiRequestLifestyle();
    RegisterTypes(webApiContainer);
    webApiContainer.RegisterWebApiControllers(GlobalConfiguration.Configuration);
    webApiContainer.Verify();

    GlobalConfiguration.Configuration.DependencyResolver =
        new SimpleInjectorWebApiDependencyResolver(webApiContainer);
}

Here is the static class to hold the info:

public static class ApplicationInfo
{
    public static string NWatchDatabaseServer { get; set; }

    public static string NWatchDatabaseCatalog { get; set; }

    public static string EntityDatabaseServer { get; set; }

    public static string EntityDatabaseCatalog { get; set; }
}

And here is the portion of the view that should be able to access these variables:

<div class="footer">
    <div class="footer-inner">
        <div class="footer-content">
            <p>@BranchCircuits_Web.Infrastructure.ApplicationInfo.EntityDatabaseServer
            \@BranchCircuits_Web.Infrastructure.ApplicationInfo.EntityDatabaseCatalog</p>
        </div>
    </div>
</div>

Does anyone have any idea why these would show up blank when the view renders?

Where is the appropriate place to be able to do something like this only when the application starts?

Upvotes: 0

Views: 1691

Answers (2)

Soma Mbadiwe
Soma Mbadiwe

Reputation: 1674

If you don't mind, you should use a normal (instantiable) ApplicationInfo class, as in, remove the statics. Then in a (static) utility class, say Utility, add a static property similar to the following:

public static ApplicationInfo AppInfo
{
    get
    {
        return HttpRuntime.Cache["ApplicationInfo"] as ApplicationInfo; //using System.Web;
        //Or, if you prefer this: 
        //MemoryCache.Default["ApplicationInfo"] as ApplicationInfo; //using System.Runtime.Caching;
    }
    set
    {
        HttpRuntime.Cache["ApplicationInfo"] = value; //using System.Web;
        //Or, if you prefer this: 
        //MemoryCache.Default["ApplicationInfo"] = value; //using System.Runtime.Caching;
    }
}

Set it in Application_Start:

var appInfo = new Infrastructure.ApplicationInfo();
SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(nWatchApp.Configuration.NWatchDatabase);
appInfo.NWatchDatabaseCatalog = builder.InitialCatalog;
appInfo.NWatchDatabaseServer = builder.DataSource;

var context = nWatchApp.GetDbContext();
builder = new SqlConnectionStringBuilder(context.DatabaseConnectionString);
appInfo.EntityDatabaseCatalog = builder.InitialCatalog;
appInfo.EntityDatabaseServer = builder.DataSource;

// Store 'appInfo' in RAM
Infrastructure.Utility.AppInfo = appInfo;

And then your div will become

<div class="footer">
    <div class="footer-inner">
        <div class="footer-content">
            <p>@BranchCircuits_Web.Infrastructure.Utility.AppInfo.EntityDatabaseServer
        \@BranchCircuits_Web.Infrastructure.Utility.AppInfo.EntityDatabaseCatalog</p>
        </div>
    </div>
</div>

Upvotes: 0

Shai Cohen
Shai Cohen

Reputation: 6249

Populating the static class in the Application_Start method is probably not the best idea. For one, it slows down the initial start up time of the application. Additionally, with this approach you can't have lazy instantiation and wait until the 1st request for that object occurs to create it. This means you might create the instance, and the 1st request for any instance of your site or that value doesn't take place until a lengthy time period later.

Here is a Lazy<T> implementation of a static class. This class and its corresponding code can live in any part of your project and be referenced from any part of your project. Using Lazy<T> will ensure the object is only instantiated when it is used somewhere in the calling code.

public class ApplicationInfo
{
    private static readonly Lazy<ApplicationInfo> _instance = new Lazy<ApplicationInfo>(() => new ApplicationInfo());

    public static ApplicationInfo Instance
    {
        get { return _instance.Value; }
    }

    public string NWatchDatabaseServer { get; set; }

    public string NWatchDatabaseCatalog { get; set; }

    public string EntityDatabaseServer { get; set; }

    public string EntityDatabaseCatalog { get; set; }

    private ApplicationInfo()
    {
        //ASSIGN VALUES HERE
        NWatchEntityApplication nWatchApp = new NWatchEntityApplication(GetNWatchConfig());
        SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(nWatchApp.Configuration.NWatchDatabase);
        Infrastructure.ApplicationInfo.NWatchDatabaseCatalog = builder.InitialCatalog;
        Infrastructure.ApplicationInfo.NWatchDatabaseServer = builder.DataSource;

        var context = nWatchApp.GetDbContext();
        builder = new SqlConnectionStringBuilder(context.DatabaseConnectionString);
        Infrastructure.ApplicationInfo.EntityDatabaseCatalog = builder.InitialCatalog;
        Infrastructure.ApplicationInfo.EntityDatabaseServer = builder.DataSource;

    }
}

Assuming the class exists in the root of the project, that is no namespace, you would access the object from a view like so:

@ApplicationInfo.Instance.EntityDatabaseServer

Please let me know if you have any questions.

Upvotes: 1

Related Questions