tags:

views:

254

answers:

3

Recently I made the decision to port my existing asmx services to WCF. I have now created a new solution which contains a WCF Service Library (this will eventually be referenced from a WCF Web site).

My old code relied heavily on HTTPContext, but its my understanding this defeats the point of WCF Services which by nature can run from any context, be that anything from a console app to an MS Outlook plugin (ok a bit extreme, but you get the idea).

Before I had my configuration in web.config, do I now still keep my configuration there, or more it to the WCF service Libraries App.Config.

With a WCF Web Site, is there now a more generic way to reference paths, not based on HTTPContext, but App Execution path, so that I can write code once that will run anywhere? (Note: In the past in asmx app execution path was bin directory).

So to summarize here are the questions:

  1. Where is the best place to store configuration values, in the web.config of WCF web site or in the app.config of the WCF service library?
  2. How can I get away from using HTTPContext for relative location of files, and implement a more generic approach, so to better take advantage of having the WCF services run anywhere.
+1  A: 
  1. Where is the best place to store configuration values, in the web.config of WCF web site or in the app.config of the WCF service library?

That depends on your hosting choice:

  • if you're hosting your WCF services in IIS, then the best place to store your config is indeed your web.config
  • if you do self-hosting, e.g. host your WCF services in a NT Service, a console app, or something else, then put the WCF config into that host app's app.config

Service libraries (DLL assemblies) don't have config files of their own - you need to put your config into the hosting app's configuration.

  1. How can I get away from using HTTPContext for relative location of files, and implement a more generic approach, so to better take advantage of having the WCF services run anywhere.

I would try to configure (e.g. in your web.config/app.config) a "base directory" which you'd then use to find your files, e.g.

<appSettings>
  <add key="BaseDirectory" value="D:\MyFiles" />
</appSettings>

Something like that should work just fine, and frees you from the HttpContext shackles :-)

Marc

marc_s
+1, thanks for further clarification on the config issues, not sure about the hard coded path. Its another key to administrate and I am sure someone will eventually forget to change that path.
JL
weöl, you could always check if your HttpContext is available (!= null), but it does introduce another dependency you might want to avoid
marc_s
+2  A: 
  1. The configuration is storred in the config file of the process hosting the WCF service. So this means that in your scenario you would include the WCF configuration in the web.config of the website referencing and hosting the services. If you were to run a unit test you would have to include the config in the app.config of the test assembly.

  2. You can always check on the location of the currently executing assembly and then work from there with relative paths. You get the location by calling:

    Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);

olle
+1 Thanks Olle for clearing this up, but I think this executing assembly is going to be located in the bin directory of the application, am I right?
JL
Correct. So you can use that path as a base and then navigate to <currentExecutionPath>/../someDir/somefile.xml to get you files. Basically it's the same as Marc his suggestion only less error prone imho.
olle
Thanks olle for this answer. I've also been beating my head off the wall trying to figure out how to construct a path in a class library, which does not have access to HttpContext.Current. +1
KP
+1  A: 

Question 1

What Marc_s said:

  • If your host is a virtual directory (IIS, VSDS, WAS, etc), then config values go in the host's web.config file.
  • If your host is an application (WinForms, WPF, Service, Console, etc) then config values go in the host's app.config file.

It gets a bit confusing because WCF allows you to have the hosting, the contracts and the implementation either crammed together in the same project or spread across separate projects. Just remember, regardless of the type of host and where the implementation code is located, config data (and data files) always go in the host project.

Question 2

Something along these lines should do the trick. These HttpRuntime properties return valid information for an IIS-hosted app even if your code does not have a valid HttpContext.

static string GetDataFilePath() {
    string path;
    if(HttpRuntime.AppDomainAppVirtualPath != null) {
        // We are hosted in IIS, so the data files are in the virtual directory's data folder.
        path = Path.Combine(HttpRuntime.AppDomainAppPath, "App_Data");
    } else {
        // We are hosted in an application, so the data files are in the same directory as the assembly.
        path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
    }
    return path ?? string.Empty;
}
  • If your host is a virtual directory, then put your data files in the App_Data folder of the host project and set CopyToOutputDirectory = DoNotCopy.
  • If your host is an application, then put your data files in the root of the host project and set CopyToOutputDirectory = CopyAlways.
Christian Hayter