tags:

views:

266

answers:

3

Hello to all,

I'll try to explain the problem as best as I can since it is a bit strange for me.

I have a C# class library that defines a bunch of classes that will used as Data Transfer Objects or DTOs.

There's a Windows Forms application that has a reference to this DTOs class library and also a reference to another class library which defines the Presenters for the Model - View - Presenter pattern.

This presenter class library has a reference to another class library which contains WCF proxy classes.

The WCF proxys class library has a reference to another class library with all the interfaces that define the contracts for the WCF services.

Finally this library with the WCF contracts has a reference to the first DTOs class library since they are received as parameters for the methods.

Now after explaining this infrastructure the problem is that the Windows form project is not compiling the error I'm getting is:

'Proheart.EmployeeView' does not implement interface member 'Proheart.IEmployeeView.JobDescriptions'. 'Proheart.EmployeeView.JobDescriptions' cannot implement 'Proheart.IEmployeeView.JobDescriptions' because it does not have the matching return type of 'System.Collections.Generic.List'.

Basically the code looks like this:

//This interface is defined on the Presenters class library.
public interface IEmployeeView  
{  
   List<JobDescriptionDto> JobDescriptions { set; }
}

//This is the form in the Windows Forms project
public partial class EmployeeView : Form, IEmployeeView  
{
   public List<JobDescriptionDto> JobDescriptions { set { ... do something } }
}

Please, I need help. I know all the class libraries separation may sound weird but it's because of the deployment strategy.

Thanks.

PS I didn't mention before that the Presenter class library does NOT have a reference to the DTO one and neither does the WCF services proxy. It seems it is being pulled from the Service Interfaces class library since if I manually add it to the Presenter one I get a circular reference error.

A: 

You missed the generic argument:

//This is the form in the Windows Forms project
public partial class EmployeeView : Form, IEmployeeView  
{
   public List<JobDescriptionDto> JobDescriptions { set { ... do something } }
}
Darin Dimitrov
A) He edited it to include it. B) He would have gotten a different compiler error if this was the case.
Samuel
System.Collections.Generic.List => strange compiler message. I was not aware of this type in the base framework class library.
Darin Dimitrov
@Samuel: This is not a reason for a down-vote. There was an error in the code, I answered the same. And, he could have got exactly this message if there is a List class somewhere, but not the one from the framework.
Stefan Steinegger
@Stefan: Sure it is, if you read the compiler error, you would know that the code sample was incomplete.
Samuel
@Samuel: Again, if he used the generic list in the interface and another class called List in the implementation , we'll get the exact error message. He only needs to forget the generic in the example and here we are. So this was the first point to make clear. People shouldn't be punished to pointing out the trivial.
Stefan Steinegger
+1  A: 

I am suspecting you might have another List class defined somewhere because of this line in the error message

because it does not have the matching return type of 'System.Collections.Generic.List'

Move your cursor over the List<> class to see if both of them are referring to System. Collections.Generic.List

oykuo
Both tooltips are identical:Class System.Collections.Generic.List<T>T is Proheart.BusinessDto.JobDescriptionDto
Sergio Romero
Just out of curiosity if you change the return type "List<JobDescriptionDto>" to type "List<int>" on both places, does it compile?I am thinking your class definition Proheart.BusinessDto.JobDescriptionDto might be out of sync in two different assemblys
oykuo
If I change it to List<int> it does compile. After that I removed all the references, compiled only the DTO class and readded it to all the projects. Still with the same result.
Sergio Romero
Here you go, it must somehow to do with the Proheart.BusinessDto.JobDescriptionDto class definition rather than List<T>. If you double click on one of the referenced dlls in that project and look at the object browser, does the assembly that contains Proheart.BusinessDto.JobDescriptionDto appears twice?
oykuo
Underneath the Proxys assembly I see this entry:{}Proheart.BusinessDto and underneath that I see a definition of the same classes as in the BusinessDto assembly.I think we are on to something. Now there is no reference on the Proxys assembly to the Dto one, but it has a reference ServicesInterfaces one which in turn has the reference to the Dto assembly. What should I do now?
Sergio Romero
Why do you reference BusinessDto assembly in ServicesInterfaces project? Is the JobDescriptionDto a data contract class? If that's the case I would suggest remove all direct reference to BusinessDto.dll except in the ServicesInterfaces project, add the web service reference in the presenter class and refer to the JobDescrptionDto class through your presenter assembly.
oykuo
Yes the JobDescriptionDto is a data contract class.I've already tried removing that reference from the Windows forms project but then the project doesn't find the JobDescriptionDto class (I have all the necessary using statements and stuff). Tried adding the ServicesInterfaces reference to the Windows forms project and still it doesn't work.
Sergio Romero
Ok so I took a look at the WCF proxy classes I generated using svcutil.exe and the tool created a partial class of JobDescriptionDto. Just for kicks I added a reference of the proxies assembly to the windows forms project and now it compiles but this really isn't right since only the presenter should know about those proxys.What should I do?
Sergio Romero
Ok I've tried this out myself. What I did was I created a WCF service and used the "Add Service Reference" to refer to it in my presenter class library. I then referenced the presenter class from my WPF project so when I double click on the presenter assembly reference I can see the auto-generated proxy class for the WCF service.
oykuo
I DON'T have to refer to the ServicesInterfaces directly because my JobDescriptionDto is now part of the Presenter class library under the namespace Presenter (NOTE: in your case it is no longer Proheart.BusinessDto.JobDescriptionDto).
oykuo
Let's assume your presenter library namespace is "Proheart.Presenter" and the name of your service reference is the auto-generated "ServiceReference1". In your WPF application you will now have to refer to your JobDescriptionDto as "Proheart.Presenter.ServiceReference1.JobDescriptionDto" not "Proheart.BusinessDto.JobDescriptionDto".
oykuo
For a proper 3 tier design, your data entity classes should be shared among all 3 layers (View, Presenter and Model). In this case it is a bit hard because your entity class (JobDescriptionDto) is essentially definied in the proxy class. If you want to be perfect, what you have to do is to create another JobDescription entity class in your presenter library, write code to translate values back and forth between JobDescriptionDto and JobDescription then use JobDescription in your WPF aplication.
oykuo
A: 

One alternative style is to allow the DTOs referenced by the proxyy classes to not be the same as the DTOs returned from the service. This may sound strange, but this is the way it would be if yhour client were written in Java, for instance. The client would only see proxy versions of the service interfaces and proxy versions of the DTO classess referred to in the service interfaces.

That reduces coupling across the service boundary.

John Saunders