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:
RainfallAPI
RainfallService
automatically.Essentially:
For clarification: I am not asking about auto-generating the client stub, I am asking about creating services on the server side.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With