2
votes

following a previous question I posted on StackOverFlow I have the following project structure to my Prism desktop application.

Class Library : Application.Common --> this contains all my DTOs and the service contracts that are defined in my WCF service layer which is an entirely different solution.

Modules: Application.Modules.ServicesModule --> in here I have added links to my WCF implementation using Add Service Reference. I also register the implementations of my types IMyServiceContract is defined in the Application.Common assembly so the initialise method looks as below:-

public void Initialise()
{
   _container.RegisterType<IMyService, MyServiceClient>(new InjectionConstructor());
}

Finally I have another module Application.Modules.FunctionalityModule this has a constructor defined as follows

   public FunctionalityModule(IMyService myService){}

when the application is trying to resolve the dependency in FunctionalityModule at runtime the following error occurs

Exception occurred while: while resolving.
Exception is: InvalidOperationException - The current type, AccountsSln.Common.ServiceContract.IMyService, is an interface and cannot be constructed. Are you missing a type mapping?

Normally, I have seen this error because a dependency has not been registered but on this occassion I know it has in the ServicesModule. Is this something to do with the registering being in different modules? Are there any other suggestions on how I can implement my project structure to support WCF services in a Prism desktop application?

Thanks

Alex

Edit: As I wanted to use a Common assembly to define my service contracts I was having problems when using Add Service Reference. It turns out that if you use Add Service Reference the generated code uses the metadata to create client side types. These have the same signature as the ones in the Common assembly but are different. To enable me to use the contracts in the Common assembly I took inspiration from this post http://xaml.geek.nz/working-slightly-smarter-with-wcf. This got me started in the right direction but I think I will have to look into making the code more suited to a production environment.

2
Are you sure the ServicesModule is being loaded? And is it being loaded before the FunctionalityModule? - John Allers
Yes if i breakpoint the Initialise in the ServicesModule it is definitely being hit. Also, the ServicesModule is before the FunctionalityModule in the Bootstrapper so I assume that means it is being loaded before. - lostinwpf
Where is the _container instance coming from in the ServicesModule? Is it being injected through its constructor or instantiated within the module? - John Allers
It is being injected in the constructor of the ServicesModule. - lostinwpf
The line _container.RegisterType(IMyService, MyServiceContractClient)(); obviously doesn't compile. Can you show us the actual code so we'll be able to help you better? - Adi Lester

2 Answers

1
votes

The problem is that you have not specified the required mapping from the interface to the implementation type. (I prefer using UnityContainerExtensions).

unityContainer.RegisterType < IStudentSearchService, StudentSearchService > ();

You also need to specify module dependencies. Your FunctionalityModule is dependent on the ServicesModule. How this is accomplished depends on how the ModuleCatalog is created. So either; in Bootstrapper's CreateModuleCatalog use moduleCatalog.AddModule, or decorating the IModules with ModuleAttribute and ModuleDependencyAttribute if using the DirectoryModuleCatalog.

Of course the UnityContainer can be configured through the app.config file.

0
votes

The generated service proxy classes are partial classes. You might be able to just make them inherit from the IMyService in the Common assembly, by adding something like following in the project where the service references are:

using Application.Common.IMyService;

namespace Application.Modules.ServicesModule
{
    public partial class MyServiceClient : Application.Common.IMyService
    {
    }
}