Prevent use of default constructor on generated web service proxy - c#

I've got a situation where I have several web services that I need to consume. I need the ability to perform custom actions in the constructor of the proxy before any calls are made (assigning the configured URL, assigning the SOAP header, etc.).
My first solution is to create a child class that derives from the generated proxy, then make those actions in the constructor of the child class. That way, app code can call the constructor of the child, and get a valid proxy that has the stuff I need.
I'm trying to prevent the app code from calling the constructor of the generated proxy, so people don't accidentally instantiate the proxy without doing my custom stuff. My first thought is to move the generated code into a separate assembly from the child, and make sure the app code only has a reference to the child assembly. This works for the most part, but...
The services contain complex types, defined in the proxy. I need the app code to reference these classes, which means the app code needs a reference to the base assembly anyway, which means they now have access to the generated constructor.
I've tried an overly-complex solution of wrapping each of the generated complex types in an interface, and then hiding the real calls and replacing them with copies of the object as the interface type. This worked once or twice, but it gets ugly really quick.
It seems that the only way I can have everything I want is to remove the public constructor of the generated proxy, and replace it with a protected constructor, then allow a reference to this assembly - they'll be able to work with the complex types, but won't be able to call the constructor. My problem is that the only way I can think of to do this is to manipulate the generated code to change the constructor.
Any ideas? I'm using WSDL.exe to generate the proxies, and there's no option there to hide the constructor. Is there another way that I'm just missing? I suppose I can write a tool to automatically modify the proxy immediately after it's generated, but that just feels ugly to me.
Thanks

Are you stuck using .NET 2.0? If not, then you shouldn't be using WSDL.EXE. You should be using SVCUTIL.EXE or "Add Service Reference".
Instead of creating a derived class, you should create your own wrapper classes, which use the proxy classes. One would use something like MyWrapper.CreateProxy(), which would return a properly-configured instance of the proxy class.
BTW, WSDL.EXE creates proxies using the legacy "ASMX" technology, which has no ability to use the types from the service.

I ended up going with modifying the proxy generated code to make the constructor protected instead of public. The call to WSDL.exe was handled in an automated project already, so it wasn't that big of a deal. This was really the only way I could get everything I wanted.

Instead of doing that, why can't you override the GetWebRequest method? It will be called before the service method call anyways.
If you have added a service reference, implementing message inspector will do same thing.

Related

Why do all screen object methods need to be declared virtual?

I've just started using white, and after successfully getting some tests working I am looking through some of the source to get a better understanding of how it all works.
One of the first things that caught me out (and keeps catching me out) is the need to have all public functions in a screen object be virtual. I have read through the documentation, and looked at the source, and I can't see any mention of why this requirement is mandatory... I can only think that the proxy enforces this requirement, but it seems to only operate on fields and doesn't seem to operate on any methods...
My guess is because White is using DynamicProxy to create proxy objects. DynamicProxy's website specifies:
You can use DynamicProxy to generate lightweight proxies on the fly for one or more interfaces or even concrete classes (but only virtual methods will be intercepted).
By marking properties and methods as virtual, the runtime will call methods on the proxy instead of calling methods on the class the proxy is based on.

Instanciate proxy of WCF service referring to the same instanciating class

I have a class implementing some audit methods (AuditcClass.cs). I have also implemented a WCF service that uses the AuditcClass.dll methods.
Now I need to be able also to reference the WCF service from within the AuditcClass. However I cannot simply use the generated proxies to reference it, since there are several conflicts with namespaces.
As first approach, I encapsulated the proxy within another namespace, solving many conflicts, but still introducing new ones with other general classes (as example, Exceptions namespace).
Is there an approach by which I could reference the web service within the class, even if the service uses the same class' methods and enums?
I was able to solve my issue by using the parameter /reference:<file path> of the svcutil tool: References types in the specified assembly. When generating clients, use this option to specify assemblies that might contain types that represent the metadata being imported.
This allowed me to exclude from the generated proxy the shared dlls avoiding reference conflicts.

Override ToString method in WCF service

This is my service generated class:
public partial class MyClass : object,
System.Runtime.Serialization.IExtensibleDataObject,
System.ComponentModel.INotifyPropertyChanged
{ }
I'm using my own service. In MyClass I have overridden ToString() but I don't have it in my client. I want either to generate it or as MyClass is partial am I able to override ToString myself?
I know that I can write in generated .cs file. What is the best way to do it and at all should I do it?
If you are defining both the client and the service, you don't need to use the WSDL-generate classes. Move the shared objects into a separate assembly, and reference it from both client and server projects. When you create the service reference, there's an "advanced" option (which I think is on by default) that reuses any known classes from the WSDL instead of generating new ones.
Even better, if you move the service contract into your shared library, you don't even need to create the service reference, you can just call the ChannelFactory directly and eliminate the entire auto-generated proxy class.
I have a demonstration on how to do both of these things on my blog: http://blog.kutulu.org/2012/03/proxy-free-wcf-ditching-proxy.html
If you absolutely need to use the WSDL from the service (e.g. you don't have control over the service side and it could change on you), then you can extend the partial classes that VS creates (as you suggested). Most auto-generate classes you get from VS these days are partial classes specifically to make this kind of extension possible. The downside, of course, is that nothing guarantees client and server's additional partial class methods are the same. I'd definitely consider this a last-resort option.
If you share the dll where overriden method exixts between client and server project, you can use the method. By default, WCF generates each class with only properties declared in the service interface. No method is generated.
You can just create a seperate dll file and put what you want to share between service and client into this dll; and add this dll as a reference to both client and service projects. By default, when you generate the proxy, it will not auto generate the shared classes.

Exposing Member Functions in a Custom Class through WCF

I have some member functions in three custom classes already created in my service. My objective is to use these custom classes on the client side to access the the member functions in the service. How do I expose these classes with all the member methods in them to the client?
I created these three classes in my service and marked them as "DataContract", and the member functions as "OperationContract". I created an Interface that defines these custom classes as OperationContracts returning an object of each of the classes through implementing them on a separate class.
Unfortunately, I couldn't achieve my objective because two of the classes have a constructor that takes some parameters, whereas the class with no constructor was accessible on the client side but I couldn't see the member methods in the class.
I need your hints on what to do.
That won't be easy to do. One way would be to share the DataContract-decorated types between the WCF server and its clients, i.e. add a reference to your service assembly in the client project and bind the service reference to that assembly reference.
However, that breaks contract implementation independence, as the exact same service assembly will need to exist on both the client and the server, and be kept synchronized every time it changes.
See here for more details.
By default and by design, WCF will only share contracts between client and server, e.g. your services ([ServiceContract]), their methods ([OperationContract]) and the data structures they operate on ([DataContract]).
WCF is a message passing system, so all the client and the server share in terms of the data being passed around is a XML serialized message format. When you add a service reference, the client-side proxy will generate a class for each [DataContract] that will look identical in XML serialized format - only the data is being moved back and forth - no behavior (no methods).
Basically, if you want to expose functionality, you need to have a service method decorated with a [OperationContract] attribute. Methods on your data classes will never be visible to the client - and that's by design.
If you control both ends of the communication and both are .NET based, you can "trick" your way around this limitation:
put all your service and data contracts into a separate class library assembly
use a reference to that common, shared assembly to create your service
before you do an Add Service Reference, add a reference to that common assembly on your client
In that case, the WCF runtime will reuse existing types from that common assembly, instead of re-creating them from the service description. And since that assembly contains the shared code that the server also uses, your classes also have their methods present.
It works ok in a .NET only scenario, but it's really kind of a dirty trick behind the proper service separation facade.

Proxy class not having equals method WCF

I have a class as DataContract in my webservice and it inherit from IEquatable.
But my siverlight webservice generated proxy class does not have equals. Can any one tell me why this is happening and is there a way achieve this?
WCF serializes only data from data contracts - no methods or behavior.
That's by default and by design - after all, WCF is a message passing system - you pass around serialized messages only.
WCF is NOT a "remote-procedure call" or "object remoting" system and thus, when creating a proxy, it will make sure the data signature on the wire will be identical (by means of XML serialization) - and that's all it does.
The only option to achieve what you're looking for would be to:
create a separate class library assembly that contains the service and data contract classes
reference that common contract assembly from both your server-side service code, as well as your client-side Silverlight app
when creating a service reference now, Visual Studio will reuse the common, shared classes in the assembly, and not re-create proxy data classes (and loosing the methods in the process)

Categories