Search code examples
wcfuwpportable-class-libraryservice-model

I can't add a reference to ServiceModel in a portable library project


I testing an UWP application and I want to use a proxy to consume a WCF service. I have a proxy that is a library for .net 4.6 but I can't add this project as reference in the project of universal application. It is normal because is a library for .net 4.6.

So I am trying to create a portable library and I have two options, to create a portable library. This option let me say what targets can I use. I select .net 4.6 and windows universal 10.0. The problem is that I can't add a reference to the System.ServiceModel that I need to use the proxy.

The other option is portable library for windows universal. In this cases I can't select the target projects, it has sense because it is only for universal applications. In this case I can add the reference to the System.ServiceModel.

I know that in a portable library I only can use the libraries of the target project more restrictive, in this case I guess that is windows universal, no .net 4.6. But then, why do I can add the reference in the portable library for universal applications and not in the portable library in which I am using .net?

I would like to have a generic portable library to be able to use the proxy in WPF applications and universal windows applications.

Thanks.


Solution

  • Unfortunately there isn't a simple subset relationship between different target frameworks; i.e. in your case UWP is not a subset of .NET 4.6, therefore when you create a portable class library targeting both, you don't simply have all the APIs from the smaller framework available.

    When dealing with clientside System.ServiceModel code the situation is even more confusing: although both target platforms include basic support for WCF proxies, the APIs are different enough that there is no portable equivalent that would be available when creating a PCL. This is the reason for the behavior that you are seeing: you can create a proxy both in a .NET 4.6 class library and in a UWP class library, but you can't create it in a portable class library targeting both of them. You will need to create 2 separate libraries.

    If you're only going to call the proxies from the platform specific WPF an UWP code, then this shouldn't really be a problem, but I suspect that you would like to call them from the business logic code which you would prefer to implement in a portable class library.

    You can achieve this as follows:

    • Create an interface for the proxy class in a common portable class library for UWP and .NET 4.6.
    • Reference this common library from both platform specific class libraries: UWP and .NET 4.6. The proxies in these 2 libraries should implement the common portable interface. I haven't tried it, but if you configure the service references to reuse the types from your portable class library, the generated proxies should already implement your interfaces. This way you could avoid create wrappers around your proxies in each of the platform specific class libraries.
    • You can now write business logic in the common portable class library and only ever work with proxies using the common interface. To get concrete instances of this interface on each platform use a portable dependency injection framework, such as Ninject.
    • In application code for each platform you will then initialize the dependency injection framework by registering the correct proxy implementation of the interface, either UWP one or .NET 4.6 one. Of course you will also reference the common portable class library from both applications, as well as the correct platform specific class library in each application.