Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generate Server Side WCF Service automatically from existing API

How would a person go about exposing method per method an API comprised of several classes through WCF without using a WCF project.

For example, let's say I have the following

public interface RainfallMonitor
{
    [ExposeToWeb]
    void RecordRainfall(string county, float rainfallInches);

    [ExposeToWeb]
    float GetTotalRainfall(string county);

    void ClearRainfall(string county);
}

I understand I could create a WCF service library as usual and just add a WCF service called "RainfallMonitor".

What I'm exploring is... is it possible/reasonable to somehow generate all of the WCF related code at compile time for an entire API without actually making the classes WCF services. Possibly using attributes such as ExposeToWeb to denote which methods to expose via the services. The resultant would function like this:

  1. Create/modify classes in project called RainfallAPI
  2. Compile and have another project/dll generated called RainfallService automatically.

Essentially:

  • If this is possible what approach could I take to actually implement it?
  • What serious pitfalls could I run into?
  • Is there any existing codebase that does something similar I could look into for inspiration

For clarification: I am not asking about auto-generating the client stub, I am asking about creating services on the server side.

like image 326
deepee1 Avatar asked Jun 23 '15 22:06

deepee1


1 Answers

I recently head of this library: Fody. As I understand, it makes it possible to hook into the build process and inject IL into the assembly. I'm not completely sure how it works, but it might be possible to search though the IL, find all the methods with the ExposeToWeb attribute and use that to emit the contract for the WCF service in to the assembly.

But on the other hand, if you are already adding attributes to the class, why not just add the correct WFC attributes to begin with, and then use SvcUtil to generate the contracts in post build?

EDIT: Here is an example of how you could use svcutil:

C#:

[ServiceContract]
public interface IRainfallMonitor
{
    [OperationContract]
    void RecordRainfall(string county, float rainfallInches);
}

public class RainfallMonitor : IRainfallMonitor
{
    public void RecordRainfall(string county, float rainfallInches)
    {
        // code
    }
}

post build PowerShell:

$svcutil = "C:\Program Files (x86)\Microsoft SDKs\Windows\v8.0A\bin\NETFX 4.0 Tools\SvcUtil.exe"
$csc = "C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe"
$assembly = "bin/debug/ProjectWithoutWCF.dll"
$service = "ProjectWithoutWCF.RainfallMonitor"
$outputns = "ProjectWithoutWCF.RainfallMonitor.Service"
$outputdir = "bin/debug"

md svcutil_tmp
cd svcutil_tmp

& $svcutil /serviceName:"$service" "../$assembly"
& $svcutil *.wsdl *.xsd /importxmltypes /out:"output.cs" /n:"*,$outputns"
& $csc /target:library /out:$outputns.dll "output.cs"

cp "$outputns.dll" "../$outputdir"
cp output.config "../$outputdir/$outputns.dll.config"
cd ..
rm -r .\svcutil_tmp

and you will need something like this in you project config:

<system.serviceModel>
  <services>
    <service name="ProjectWithoutWCF.RainfallMonitor" >
      <endpoint address="" binding="basicHttpBinding" contract="ProjectWithoutWCF.IRainfallMonitor">
      </endpoint>
    </service>
  </services>
</system.serviceModel>

Its a little fiddly and you will most likely need some tweaking to the script and the config. But the result is that you have a ProjectWithoutWCF.RainfallMonitor.Service.dll file with the WCF service contracts.

like image 198
Jon List Avatar answered Nov 01 '22 13:11

Jon List