2

This is as much a design as a technical question. I'm not sure I am doing this right...

I have a WCF API which communicates with a DB and passes back a Person object (which is defined in a separate .dll) This has both methods and attributes. The object is being sent from the WCF to the calling client.

I want to call the Person's methods on the client. I understand that these cannot be sent downstream from the API. However, if I reference the same .dll that the WCF uses should I be able to cast the API Person to a .dll Person then run the methods?

I hope it is clear what I am trying to achieve.

InteXX
  • 6,135
  • 6
  • 43
  • 80
sam
  • 23
  • 1
  • 3

3 Answers3

2

WCF works through data contracts. These are models of the data to return, like a Person object with its properties. Don't worry about methods during transportation of the object from Service to Client. If a data contract is used, and you will reference WCF, the proxy class will generate a Person object.

If your logic is more complex I suppose it depends on the situation you have. Let me describe in a few words:

  1. If you can't change the source of the class and you want to call a public method, it is better to use reflection. So, you receive an object from WCF, set the Person object's properties with the values returned, and then call the method.

  2. If you can change sources of the class, you can create a base interface IPerson, implement this interface with properties of the Person object in the class and return an IPerson object. In this case, you will be able to perform the cast.

More details: Ok, let me provide you with more details:

  1. As a best practice, I recommend creating separate classes with interfaces. This should be a data contract interface which will describe your object. Something like this:

    [DataContract] 
    public interface IPerson
    {
       [DataMember]
       public int Identifier { get; set; }
    
       [DataMember]
       public string First { get; set; }
    
       [DataMember]
       public string Last { get; set; }
    
       public string GetSomething();
    }
    
  2. Method on WCF you are implementing should return IPerson type.

  3. In shared class please implement the interface IPerson for your Person object.
  4. Reference this assembly in your Service and Client projects.
  5. Add a web reference to the WCF service in your client project.
  6. Your method will return an object of type IPerson, so you can use your Person object from the shared library, and use all its methods.
InteXX
  • 6,135
  • 6
  • 43
  • 80
dimko1
  • 872
  • 7
  • 15
  • Thanks for the quick reply, the external dll is my own so I can modify the source, can you explain a bit more about option 2. I like the concept but don't fully understand. – sam Oct 10 '11 at 22:00
  • So you have a dll containing data contract interfaces, and also a shared dll containing the implementation of those interfaces? And I should reference both dll's from the WCF Service project as well as from the client project? Then what's the use of implementing a separate interfaces dll? – comecme Jun 04 '12 at 19:51
  • I am getting complaint that "[DataContract]" is not valid for interface – OmGanesh Nov 07 '18 at 16:22
1

Since you are referencing the same dll, and WCF can be strong typed, you should be able to call the methods on the Person response object without casting. Make sure when you define the Person class that you are using the DataContract attribute.

In the following example, the Person class will be serialized by WCF with the three data members on the server side. The client side WCF will deserialize response... creating the class Person. So on the client side, you can call FullName() and it will work without casting.

 [DataContract]
 public class Person
{
   [DataMember]
   public int Identifier { get; set; }
   [DataMember]
   public string First { get; set; }
   [DataMember]
   public string Last { get; set; }
   public string FullName()
   {
      return First + " " + Last;
   }  
}
John E
  • 166
  • 1
  • 10
  • That is how my object looks, I can view int, first and last on client side but cannot see the method... pService.Person p = API.GetPerson(123); – sam Oct 10 '11 at 22:05
  • Is the method scoped as Public? – John E Oct 10 '11 at 22:30
1

WCF supports the ability to re-use references that are already included in the project. In this sense, you can create a contracts assembly (an assembly that contains your thin domain models (e.g. Person etc) which you can add your own logic to.

You can then add assembly to both your WCF service, and the calling client projects, and instruct WCF to re-use any existing references. This way, what is pulled back from your service is deserialised into local copy of a Person, but not a Person that would generated as a proxy, you actually get a full instance, on which you can perform method calls.

Don't forget through, you are marshalling by value in this case. Any changes you make to the Person instance are local to the client only, you would need to pass it back upstream to your WCF service again (through serialisation) for the service to recognise any changes and act accordingly.

Matthew Abbott
  • 60,571
  • 9
  • 104
  • 129
  • Is there a better way to do this? create a Person object on both server and client maybe? I thought this way I would only have to create one Person object plus several others that can be shared between service and client. I am looking for the most elegant solution it is a personal project I'm working on. – sam Oct 10 '11 at 22:19
  • I think you're missing the point. You only implement `Person` once. In a shared assembly (a contracts assembly). You then reference this on the service, and on the client. – Matthew Abbott Oct 10 '11 at 22:30
  • No I understand and as of 15 minutes ago have a working solution. Thanks! However, is this the best way to do this in a shared assembly? I'm new to WCF. Do you foresee any issues with it? – sam Oct 10 '11 at 22:34
  • Well, its really the only way you can do. `[DataContract]` doesn't support method calls, so in that sense, sharing the assembly between multiple projects it not a bad idea. – Matthew Abbott Oct 10 '11 at 22:37