Ales Potocnik
Ales Potocnik

Reputation: 3087

Application root path

I've recently been having some issues with correctly discovering application root path in c#. I want my applications to use the correct folder in following instances:

Namely I need this for a logging assembly which is shared across all those types of applications. It's using log4net and it needs to correctly resolve physical path internally - inside logging assembly.

Because log4net requires either a call to BasicConfiguration.Configure to load it from web.config / app.config. Issue with this is it doesn't set up a file watcher so changes are not monitored. Solution is to have a log4net.config file separately.

Now, I don't like placing things inside bin, bin/debug or bin/release folder since it is never included in source control. Instead for things like that I have a Config folder in application root. So that you end up with ~\Application\Config\log4net.config.

In the static logger there are 2 methods:

    public static string GetRootPath()
    {
        var debugPath = string.Empty;
        #if (DEBUG)
        debugPath = "..\\..\\";
        #endif
        return Path.Combine(AppDomain.CurrentDomain.BaseDirectory, debugPath);
    }

    public static void Init(string loggerName)
    {
        LoggerName = loggerName;
        XmlConfigurator.Configure(new FileInfo(Path.Combine(GetRootPath(), "Config\\log4net.config")));
    }

So you can just call Logger.Init() in Application_Start or inside Main() for console apps. This works great for console applications but not for web applications since AppDomain.CurrentDomain.BaseDirectory points to web application root and not to it's bin folder (which also has no debug or release).

Has anyone got a reliable way to resolve root path for all above requirements? So - what should GetRootPath be doing?

PS: I know I could be checking if (HttpContext.Current != null) then don't merge debug path in but there must be a more elegant way?

Upvotes: 3

Views: 10645

Answers (1)

Hans
Hans

Reputation: 13030

You could use the CodeBase property of the Assembly class to determine the path to the executing assembly:

public static string GetRootPath()
{
    var debugPath = string.Empty;
    #if (DEBUG)
    debugPath = "..\\..\\";
    #endif
    return Path.Combine(Path.GetDirectoryName(new Uri(Assembly.GetExecutingAssembly().GetName().CodeBase).LocalPath), debugPath);
}

Note, for web applications and windows services the file path is in file URI scheme format. So, I use the Uri class to convert the path to standard windows path format.

Hope, this helps.

Upvotes: 1

Related Questions