How to use WCF Message for writing Multiple Objects - wcf

I have this requirement, I have two classes Person and Department and i want to send object of these two classes in the System.ServiceModel.Channels.Message? How can i accomplish this. I there any best way alternative to that.
Thanks in advance.

Message class has a static method called CreateMessage which has an overload to take any object that can be serialized.
Create a new datacontract\class with instances of Person and Department object. Pass the wrapper object to CreateMessage to serialize

Related

Restler - Call method from another API class

In my Restler index.php let's say I've done this:
$r->addAPIClass('Person');
$r->addAPIClass('Team');
And now I'm inside one of the methods defined in Person, and I have a need to call one of the methods defined in Team. What's the right way to get a handle to the Team API so that I can call one of its methods?
There is nothing special, doing it with Restler.
If it is a static method directly call Team::method(parameter)
Otherwise create an instance either
at constructor if you need it in many methods and store it in a private variable
at the method level
If you are using a database model, it may already provide you with an instance of team as a relationship

WCF Custom Class Arguments

I have a WCF method which takes an argument that is a custom class, say,
void MyWCFMethod(MyCustomClass MethodArgument)
In the above, MyCustomClass has a number of constructor overloads. The service has a reference to the class but not the client. I want to allow the client to use the other overloads but the default constructor is the only one that seems to be allowed. Is there a way to do this?
You can certainly do this, but I think it is important to know why the Data Transfer Objects (DTOs) do not expose logic over the service reference.
The WSDL\XSD metadata that is used in order to generate the client proxy to access the WCF Service only describes the web service by the operations exposed and the datatypes exchanged.
Specifically, XSD only describes the structure of your DTOs and not the logic - that is why there is only the default constructor and public properties/fields available on the client proxy.
So the solution is to put all of your custom classes exchanged between the client and service in a separate shared library. This way both sides of the wire have access to the additional logic (like your parameterized constructors) that you could not obtain via WSDL\XSD.
I guess - no!
As I understand MyCustomClass is data contract and marked by [DataContract] attribute.
So WCF runtime will use DataContractSerializer (by default) to deserialize data from received message to the instance of object.
So where can DataContractSerializer get additional parameters for your specific constructors?
Instance of data contract must have public parameter-less constructor to be instantiated.
But maybe you can write own serializer (but keep in mind that DataContractSerializer cannot be inherited)... and provide additional data to constructor. But if you can get that information somewhere just do it in public parameter-less constructor of your data contract.
So I guess you are doing something wrong. Try to specify what is the goal to pass data in constructor in your case. Maybe your app can use some another solution.

Where to put methods that interact with multiple classes

I have a class called Contact and one called Account
and I have a method called public static Account GetAccount(Contact c) {...}
Where is the best place to put this method? What design patterns should I be looking at?
A) With the Contact class
B) With the Account class
C) Have the method accessible in both classes
D) Somewhere else?
There are probably many good answers to your question. I'll take a stab at an answer, but it will have my personal biases baked in it.
In OOP, you generally don't see globally accessible) functions, disconnected from, but available to all classes. (Static methods might be globally available, but they are still tied to a particular class). To follow up on dkatzel's answer, a common pattern is in OOP is instance manager. You have a class or instance that provides access to a a database, file store, REST service, or some other place where Contact or Account objects are saved for future use.
You might be using a persistence framework with your Python project. Maybe something like this: https://docs.djangoproject.com/en/dev/topics/db/managers/
Some persistence frameworks create handy methods instance methods like Contact.getAccount() -- send the getAccount message to a contact and the method return the associated Account object. ...Or developers can add these sorts of convenience methods themselves.
Another kind of convenience method can live on the static side of a class. For example, the Account class could have a static getAccountForContact() method that returns a particular account for a given Contact object. This method would access the instance manager and use the information in the contact object to look up the correct account.
Usually you would not add a static method to the Contact class called getAccountForContact(). Instead, you would create an instance method on Contact called getAccount(). This method could then call Account.getAccountForContact() and pass "self" in as the parameter. (Or talk to an instance manager directly).
My guiding principle is typically DRY - do not repeat yourself. I pick the option that eliminates the most copy-and-paste code.
If you define your method in this way, it's not really connected with either of your classes. You can as well put it in a Util class:
public class AccountUtil{
public static Account getAccount(Contact c){ ... }
// you can put other methods here, e.g.
public static Contact getContact(Account a){ ... }
}
This follows the pattern of grouping static functions in utility classes like Math in Java / C#.
If you would like to bound the function to a class in a clear way, consider designing your class like this:
public class Contact{
public Account getAccount(){ ... } // returns the Account of this Contact
// other methods
}
In OOP it is generally recommended that you avoid using global functions when possible. If you want a static function anyways, I'd put it in a separate class.
It depends on how the lookup from Contact to Account happens but I would vote for putting it in a new class that uses the Repository pattern.
Repository repo = ...
Account account = repo.getAccount(contact);
That way you can have multiple Repository implemtations that look up the info from a database, or an HTTP request or internal mapping etc. and you don't have to modify the code that uses the repositories.
My vote is for a new class, especially if the function returns an existing account object. That is, if you have a collection of instances of Contact and a collection of instances of Account and this function maps one to the other, use a new class to encapsulate this mapping.
Otherwise, it probably makes sense as a method on Contact if GetAccount returns a new account filled in from a template. This would hold if GetAccount is something like a factory method for the Account class, or if the Account class is just a record type (instances of which have lifetimes which are bound to instances of Contact).
The only way I see this making sense as part of Account is if it makes sense as a constructor.

How to Define method in DataContract class

I want to add some method in class that i define as a 'DataContract' class.
I need that the client will call those method in some cases.
Is it possible?
How can i do it ?
Thanks for any help.
If you mean that you want to add a service call to a DataContract then that is not possible. If you want to add some helper methods to the data contract and you want to make those available to the client as well then you can do that if you are also in charge of the client code or you are willing to share the library containing the data contract class with the clients.

Generic DataContract in Agatha WCF

I am trying to use Generic DataContract class so that I don't have to implement several types for a collection of different objects.
Exp :
I have a Profile object which contains a collection of objects.
So I want to have one Profile<Foo> and Profile<Foo1> where profile contains a collection of Foo or Foo1 objects.
I have been reading that WCF does not support generic classes and actually the error that I get is the following.
Type 'GL.RequestResponse.ProfileResponse1[T]' cannot be exported as a schema type because it is an open generic type. You can only export a generic type if all its generic parameter types are actual types.`
Now the ProfileResponse is this Profile object that I am trying to use.
Now in my host I am doing the following. :
ServiceConfig(typeof(ProfileHandler<EducationResponse>).Assembly,
typeof(ProfileRequest).Assembly,
typeof(Container)).Initialize();
This is dhe definition of the handler with the datacontract.
public class ProfileHandler<T> : RequestHandler<ProfileRequest,
ProfileResponse<T>>
The Container is using Windsor Container to register the objects.
The registration works fine but after I instantiated the Service Host for WCF processor, and call Open Method of the host I get the above error.
Is there really no way for me to write generic response requests for wcf with agatha ?
It feels like such a waste to have to define a Profile container class for each type being contained in that collection.
thanks.
One cannot have open generic handlers, because the server side needs to know what the type is.
One can use so called closed generic methods. This way the server side knows the types for witch to load the handler.
Also, one could potentially configure Agatha so that it allows to receive extra information related to the request. In this case, it would be the type wrapped in the response.
One could do this by defining a a BaseRequest class and having all the request extend this class. This class can have a property which takes the type of the response. Or the type to be wrapped in the response.
In the process, when examining the request, the process can get the type to be wrapped in the Response, so that i knows how to load the class.
I have not implemented this, since it would take too much time and I am not sure I want to be responsible for maintaining Agatha for our application, but this is how I would do it.