views:

59

answers:

2

Hello, I'm working on an open source project (Logbus-ng), and I need to implement a web service spawned by a console application in a way that works both on Windows and Mono.

Currently, thanks to the tutorial by MSDN Magazine, I succeeded in doing this on Windows. A console application can spawn its own web server and actually open a web service interface to the external. The problem is that this doesn't work in Mono, reasonably because of a Mono bug.

Chatting with Mono developers, they suggested me to use the Mono.XSP assembly to enable the ASP.NET pipeline into console applications, so I think I'll use different implementations of the web service activator depending on the configuration.

Now my question is: since Mono.XSP is available in GAC in all Mono distributions (ie. when using xbuild under Linux) but is not available in Windows unless someone installs it into the GAC, and I don't want to ship Mono.XSP with my software, neither force someone to install Mono if they don't need it (ie. if compiling under Windows), can I set a reference to Mono.XSP assembly in GAC that is enabled only if the MONO compilation flag is enabled? When this flag is enabled, my code will obviously be referencing Mono.XSP instead of HttpListenLibrary covered in the tutorial linked above, and the reference will be used by the compiler correctly.

Thank you in advance.

+1  A: 

I don't know if this can be achieved. But you could consider late binding the assembly using reflection, getting an instance of the objects and methods you need. This gives you an idea of you would do that:

// Wrapper class:
public class Listener
{
    public void Start()
    {
        bool useMono = true; // TODO: Get this from config
        if (!useMono)
        {
            // Bind directly to this as it will be available in Mono too
            HttpListener listener = new HttpListener();
            listener.Prefixes.Add("http://localhost:8081/foo/");
            listener.Prefixes.Add("http://127.0.0.1:8081/foo/");
            listener.Start();
        }
        else
        {
            Assembly asm = Assembly.Load("TheNameOfTheAssembly");

            Type type = asm.GetTypes().Where(x => x.Name == "TheType").FirstOrDefault();
            object obj = Activator.CreateInstance(type);
            MethodInfo mi = type.GetMethod("NameOfMethod");
            mi.Invoke(obj, null); // invoke with list of parameters
        }
    }
}

You can then replace this sort of implementation when the bug has been fixed.

steinar
Well... I might mean #if MONO instead of if(useMono) :) but that can be an idea. +1 on you
djechelon
Yes, if you don't mind making different builds. This allows you to have only one build, but the setup program would have to provide a specific config for Mono.
steinar
I currently use different builds because of other Mono issues, so it's OK for me
djechelon
+3  A: 

Use an MSBuild condition.

For example, suppose your project has a configuration called "DebugMono", which is the Mono version of the usual "Debug" configuration, simply place a condition attribute on the appropriate reference item element that checks the "Configuration" property value:

<Reference Include="Mono.Xsp" Condition="'$(Configuration)'=='DebugMono'" />
mhutch