I wrote about implementing WCF service in IronPython a couple of weeks ago. Meanwhile I pushed Shri a little bit with the clrtype.py and he has implemented ClrInterface metaclass there so we can create the whole WCF service in IronPython now.
The IronPython interface implementation is straightforward:
import clr import clrtype clr.AddReference('System.ServiceModel') from System.ServiceModel import ( ServiceContractAttribute, OperationContractAttribute) OperationContract = clrtype.attribute( OperationContractAttribute) class ImyService(object): __metaclass__ = clrtype.ClrInterface _clrnamespace = "TestServiceInterface" _clrclassattribs = [ServiceContractAttribute] @OperationContract() @clrtype.accepts(int) @clrtype.returns(str) def GetData(self, value): raise RuntimeError("this should not get called")
Also switching from C# interface to IronPython interface is easy:
import clr import clrtype clr.AddReference('System.ServiceModel') from TestServiceInterface import ImyService from System import Console, Uri from System.ServiceModel import (ServiceHost, BasicHttpBinding, ServiceBehaviorAttribute, InstanceContextMode) class myService(ImyService): __metaclass__ = clrtype.ClrClass _clrnamespace = "myWcfService" _clrclassattribs = [ServiceBehaviorAttribute] def GetData(self, value): return "IronPython: You entered: %s" % value sh = ServiceHost(myService, Uri( "http://localhost:9000/myWcfService")) sh.AddServiceEndpoint(clr.GetClrType(ImyService), BasicHttpBinding(), "") sh.Open() Console.WriteLine("Pressto terminate\n") Console.ReadLine() sh.Close()
Notice that we call ServiceHost with myService which is the type and not the instance of our service. Because of this, the ServiceBehavior attribute does not need to have InstanceContextMode.Single parameter.
Finally, here is the test client:
import clr clr.AddReference('System.ServiceModel') import System.ServiceModel from TestServiceInterface import ImyService mycf = System.ServiceModel.ChannelFactory[ImyService]( System.ServiceModel.BasicHttpBinding(), System.ServiceModel.EndpointAddress( "http://localhost:9000/myWcfService")) wcfcli = mycf.CreateChannel() print "WCF service returned:\n%s" % wcfcli.GetData(11)
The disadvantage of having just a single service instance is gone,
the harder configuration remains. One new disadvantage can be
it is not possible (yet) to compile the interface and save it to
disk nor use it from other .NET languages.
Edit 22. 11. 2009: See WCF Service in pure IronPython with config file
6 comments:
Now if the interface could be implemented as decorator, the python code would be even closer to the C#.
Yes, it would be nice to implement it as decorator. Unfortunately it is not possible because it has to use metaclasses - see DevHawk's blog:
I wish I could use Python’s class decorators for custom class attributes, but class decorators run after metaclasses so unfortunately that doesn’t work.
is it then possible to implement the wcf service in ironpython and the client in csharp and vice versa ?
It is possible.
The only thing which is not possible is to host IronPython WCF service in IIS.
I know it's a while since you posted this tutorial, but I've encountered problems with metaclasses that I can't seem to get around it.
When i load the python-file (Note: Inside ACAD 2016), i get an Metaclass confict between ClrInterface and ClrClass. However, with your old example, with the interface written in C#, i don't encounter this problem.
Have you any advice for me?
Greetings from Switzerland
I'm sorry but no idea - I would guess it is specific to ACAD 2016.
Post a Comment