8

I am trying to write some code in C# that will call a WCF service on the fly by importing the WSDL, examining it and then making calls to it dynamically.

The service I am calling can change from time to time - so if it does I want my client to know about new methods and new input parameters and output parameters to the calls, without rebuilding my client.

One possible solution to this is to import and compile a service reference on the fly.

Outlined here: Creating an assembly on the fly from a WSDL

I would like to avoid the generation of an assembly and then reflecting over it if possible.

I looked into the code of the dynamic proxy in the link and they use a framework class to do the import. This class is the WsdlImporter. So I had thought great - I can use that and examine the WSDL schema and determine what calls are present and what inputs and outputs are available.

The problem is that the type information is missing in the MessagePartDescription objects that the WsdlImporter creates. Apparently this is missing because it cannot find the types yet - see the response to the question from Brian.

So any advice on how I should proceed? Am I completely on the wrong track here?

TrueWill
  • 25,132
  • 10
  • 101
  • 150
Neil
  • 1,605
  • 10
  • 15
  • Can you give a real-world example of how this would be useful? Is there a UI presented to a user of your client that lets them select methods to call, perhaps some sort of scheduler or something? Also, what's wrong with creating an assembly on the fly? That sounds pretty straightforward. Are you envisioning something being simpler than reflecting? I have trouble imaging what that would be. – JohnOpincar Jan 25 '11 at 02:43
  • 1
    This will be used to call a WF service. The workflow can change - steps can be added/removed etc. – Neil Jan 25 '11 at 03:00
  • @JohnOpincar - My objection is not to reflection - it is to the on the fly compilation of the assembly. It does seem like it is an approach that may cause security issues at some point, and *may* be fragile. Also it seems odd to me that when all the information is in the WSDL and given that eventually the calls will all be marshaled through something that looks a lot like a dynamic API that building a dynamic layer with reflection on top of a static layer that was dynamically created that is then mapped to a dynamic layer is a bit much. Creating the assembly on the fly is my backup plan. – Neil Jan 25 '11 at 03:08
  • 1
    Parsing a WSDL accurately is not trivial. I would favor using the tools built into the platform to accomplish this (dynamic assembly with reflection) over trying to implement that myself. Unless I'm misunderstanding your concept, the dynamic assembly generation will be the least of your fragility concerns. – JohnOpincar Jan 25 '11 at 14:11
  • 1
    @John - I agree, I do not want to get into the business of of WSDL parsing. The .net framework has a WSDL parser built in: `WsdlImporter` - but it does not expose information about the types of operation parameters. Somehow the other framework parts can get this information out of the WSDL importer - but a mere mortal such as myself cannot. – Neil Jan 25 '11 at 14:38
  • 1
    @Neil: many parts of .NET create code on the fly, including ASP.NET. There are no particular security issues involved with this. Do you trust the source of the WSDL? If yes, then the WSDL can't cause you any security problems. – John Saunders Jan 26 '11 at 21:03
  • @John - I am probably just being skittish about it. I suspect that if you are saying "get over it and just use the dynamic assembly creation code" you may be right. – Neil Jan 26 '11 at 21:58
  • @Neil: ASP.NET, XML Serializer, and many, many other parts of .NET use dynamic code generation and assembly creation. Let them do their job. – John Saunders Jan 26 '11 at 22:13
  • @John - I am coming round to your point of view ... It might take another day :) – Neil Jan 26 '11 at 22:37

2 Answers2

5

This is probably not an answer but I will post it as one to fully describe my opinion.

Dynamic proxy:
IMO this is example of wrong usage of technology. It is elementary behavior of WSDL - if it changes you have to change client or you have to make good WSDL versioning and create new client.

You still have to somehow say your client to get WSDL - does it mean that you will parse WSDL before each call? Doesn't seem like a good idea.

Information about types is really not part of WSDL because by default WSDL is generated as interoperable. CLR types are not operation needed for interoperability. When you create service proxy by Add service reference or Svcutil it will generate code for types defined in WSDL. That code then need to be compiled.

You can try to use NetDataContractSerializer instead of default DataContractSerializer. NetDataContractSerializer adds CLR type information into WSDL but I still expect that new types must be known to your clients - it means deploying new assembly with types and use it by clients. This almost sounds like same approach when simply deploying assembly with new static client proxy.

Dynamic WF client
I also don't see too much usage of this architecture - you still need to change client to reflect new WF steps, don't you?

Changing the WF
Are we talking about Windows Workflow foundation? I can hardly imagine scenario where you create WF, expose it as a service and then change it. When you expose WF as service you are probably defining long running WF. Long running WFs use persistance which is based on serialization (at least in WF 3.5 but I believe it is same in WF 4). When you change WF definition, all persisted WFs are most probably doomed because they will never ever deserialize. This situation is usually solved by parallel deployment of new and old version where old version is only used to finish incomplete WFs. Again it means new clients.

Ladislav Mrnka
  • 360,892
  • 59
  • 660
  • 670
  • Thanks for your comment, as you say it does not solve my issue but I will +1 it because it is thought provoking - I agree with your assessment of WSDL as it relates to types. However if the WsdlImporter would let me see what the WSDL types were I could get to where I want to go. I don't need the CLR type. See my next comment regarding Dynamic Clients. – Neil Jan 26 '11 at 21:44
  • 1
    We are talking about long running WF classes. There is no reason why adding a step to my workflow should require the rebuilding of a client that does not perform that step. Additionally if you want to build a backbone to manage your clients interactions with the workflow and have all the clients conform to a standard interface you need to funnel all the calls through a narrower API than the API that a WF service will create. – Neil Jan 26 '11 at 21:55
  • @Neil: In such case I would probably go different direction. I would maintain all this complexity on the server side. It means hosting WF in your process and exposing web service with well known interface prepared for WF changes. It is high level idea but it should be possible and it would be easier than "dynamic web service client". – Ladislav Mrnka Jan 27 '11 at 23:12
1

If you look at the problem from a different angle. Do you need to regenerate the proxy each time or do you need a contract that continues to work when things change?

WCF has a mechanism for this IExtensibleDataContracts see: http://msdn.microsoft.com/en-us/library/ms731083%28v=VS.100%29.aspx

Best practices for versioning of contracts can be found here

Shiraz Bhaiji
  • 64,065
  • 34
  • 143
  • 252
  • +1 Thanks for the answer - it may be useful to others. Unfortunately we have limited control over the WCF service that WF generates, so we can't really go that route. – Neil Jan 31 '11 at 16:25