views:

265

answers:

2

I created a WebService using the .NET 2.0 framework, a class based on an interface that has the WebServiceAttribute and hosting it using IIS and a ASMX file. The WebService currently loads its configuration from one XML file.

I'd like to create multiple instance of this service where each loads it own configuration.

By coping the ASMX file I can create a clone of the webservice under a different name which will be based on exact the same implementation. But it also loads the exact same configuration file which makes it rather useless.

So my question is: What is the best way to create an arbitrary number of WebServices that are based on one class, living in one IIS virtual directory where each is loading a different configuration file?

Solution

With the help of Pavel Chuchuva's answer I created the following code to handle the loading of the configuration:

public class WebConfigManager
{
    public static T Load<T>() where T: new()
    {
        string location = 
            HttpContext.Current.Request.PhysicalPath + ".config";

        if (HttpContext.Current.Cache[location] is T)
        {
            return (T)HttpContext.Current.Cache[location];
        }

        using (Stream s = 
            new FileStream(location, FileMode.Open, FileAccess.Read))
        {                
            return (T)(HttpContext.Current.Cache[location] = 
                new XmlSerializer(typeof(T)).Deserialize(s));                
        }
    }
}

// example of the usage of WebConfigManager
public class MyWebService : IMyWebService 
{
    Config config = WebConfigManager.Load<Config>();
...
+1  A: 

I suggest placing the asmx in different folders and placing a web.config in each of those folders with the setting for that specific instance of the web service. This is the easy and fast way

OR

you could use Web Service Enhancements 3.0 and create a WSE router, redirect a calls to a ASMX to that router and let the router forward the call to the right web service instance and pass additional config. This a more complex way of doing it but it enables u to use a single instance of the web service that's picks the right configuration based on the parameters the router passes it. For more info on WSE3.0 I point you to the MSDN.

Hope this helps!

norbertB
@All: WSE is obsolete. It is very nearly unsupported, and does not work in Visual Studio 2008 or above. Do not use it unless you have no choice at all.
John Saunders
I now know had to catch up!
norbertB
+1  A: 

Copy and paste .asmx file to create multiple instances of your web service (e.g. Service1.asmx, Service2.asmx and so on).

Load configuration file based on Context.Request.FilePath value:

public string LoadConfig()
{
   string configPath = Server.MapPath(this.Context.Request.FilePath + ".xml");
   using (XmlReader reader = XmlReader.Create(configPath))
   {
      // Will read Service1.asmx.xml, Service2.asmx.xml and so on
   }
}
Pavel Chuchuva
@Pavel: good example, but your XmlReader creation should be in a using block. I suggest you edit your answer before someone copies the code without realizing it's only an example.
John Saunders
@John: This is done now.
Pavel Chuchuva