Passing badly structured information to WCF method. Best practice
I have legacy Reporting Engine class that is responsible for 50+ reports with a single method CreateReport(Guid reportId, ReportParams params);
Reports require 12+ of different parameter types (Guid, int, bool, enumerations) and their combination. For example:
- Report #1: No parameters are required
- Report #2: 2 Booleans (checkboxes populate by user)
- Report #3: Guid (personId) & integer (year to start with)
- Report #4: Guid (personId) & PersonType (enumeration)
ReportParams is a class with 12+ properties and arrays that are populated before calling开发者_StackOverflow the method. But most of them are unused per call. Report Engine class checks that appropriate properties are populated and uses strong type information access.
Everything was ok until I decided to make reporting engine WCF friendly. Every time I add new parameter type I have to rebuild server, update proxy (that leads to clients reinstall), and make sure that ReportParam structure is converted correctly between WCF-friendly version and Reporting Engine version.
I wonder how to minimize all this conversions, checks, client reinstallations e.t.c. May be I shall refactor ReportParam to XML document? It will make proxy stable, ReportParams wcf friendly, but I'll have to refactor strong type information access in the Report Engine class.
What will you suggest?
Do you control both ends of the WCF communication??
In that case:
- put your service contract (interface) and data contracts into a class library assembly
- share that assembly between server and client
- on the client, use
ChannelFactory<T>
andfactory.CreateChannel()
to manually create the communication channel
In this setup, you make the change to the data contract once, rebuild your service and client, and you're done. No messy "Update Service Reference" etc.
I'm not exactly clear on your issue, but let me not stop that in my insatiable quest for rep.
First thing, I'd definitely suggest placing a "firewall" between the reporting code and the WCF code. You should treat your WCF code as a facade, insulating it from changes to your reports as much as possible. If your reporting engine requires a change, you can rewrite the server code without messing with client code.
Next thing is that I'd get rid of the idea that you can generically serve up X number of reports via a single call. You should expose every report as a separate call, each having a signature which takes in the exact number and type of arguments the report requires.
But, you ask, what happens when the report changes, or a new report must be added? You cannot (i.e., should not under any circumstances) version interfaces, and your service contract IS an interface. Therefore, as reports change, you must mark the OLD report method as obsolete. Add the updated method (as well as methods for new reports) to a NEW service contract that will be served along side of the old one. If people try to use the old report method, either attempt to make due (apply reasonable defaults to those arguments not provided) or throw an exception. If a report changes drastically to the point where a client reinstall is required, consider adding the updated report as a new one.
Adding updated reports and/or new reports becomes a simple matter of dropping a new binary on the server and changing the .config file.
精彩评论