A colleague had this error occur while setting up a production system. Everything had been fine in development, but Dependency Injection seemed to be throwing a wobbly when it tried to load the service we’d written for adding/removing contacts from a subscription list.
Edit: I raised this problem with Sitecore and got a helpful response: https://andrewwburns.com/2018/08/17/avoiding-the-iclientapiservice/
The error was:
[InvalidOperationException: Unable to resolve service for type 'Sitecore.EmailCampaign.Cd.Services.IClientApiService' while attempting to activate 'XXXXXXXX.Foundation.Exm.Services.ExmMailService'.]
Microsoft.Extensions.DependencyInjection.ServiceLookup.Service.PopulateCallSites(ServiceProvider provider, ISet`1 callSiteChain, ParameterInfo[] parameters, Boolean throwIfCallSiteNotFound) +381
Microsoft.Extensions.DependencyInjection.ServiceLookup.Service.CreateCallSite(ServiceProvider provider, ISet`1 callSiteChain) +354
Microsoft.Extensions.DependencyInjection.ServiceProvider.GetResolveCallSite(IService service, ISet`1 callSiteChain) +31
Microsoft.Extensions.DependencyInjection.ServiceProvider.GetServiceCallSite(Type serviceType, ISet`1 callSiteChain) +134
Microsoft.Extensions.DependencyInjection.ServiceLookup.Service.PopulateCallSites(ServiceProvider provider, ISet`1 callSiteChain, ParameterInfo[] parameters, Boolean throwIfCallSiteNotFound) +99
Microsoft.Extensions.DependencyInjection.ServiceLookup.Service.CreateCallSite(ServiceProvider provider, ISet`1 callSiteChain) +354
Microsoft.Extensions.DependencyInjection.ServiceProvider.GetResolveCallSite(IService service, ISet`1 callSiteChain) +31
Microsoft.Extensions.DependencyInjection.ServiceProvider.GetServiceCallSite(Type serviceType, ISet`1 callSiteChain) +134
Microsoft.Extensions.DependencyInjection.ServiceProvider.CreateServiceAccessor(Type serviceType, ServiceProvider serviceProvider) +73
System.Collections.Concurrent.ConcurrentDictionaryExtensions.GetOrAdd(ConcurrentDictionary`2 dictionary, TKey key, Func`3 valueFactory, TArg arg) +81
Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Type serviceType) +80
Sitecore.Mvc.Controllers.SitecoreDependencyResolver.GetService(Type serviceType) +38
Sitecore.Mvc.Controllers.SitecoreControllerFactory.ResolveController(Type type) +40
Sitecore.Mvc.Controllers.SitecoreControllerFactory.CreateController(RequestContext requestContext, String controllerName) +95
[ControllerCreationException: Could not create controller:
...
So, it transpired this was caused by the server’s role setting. This is new in Sitecore 9. It lets you pick whether a server is standalone, CM, CD, Reporting, or Processing…
Unfortunately, it appears that the configuration Sitecore.EmailExperience.ContentDelivery.config removes the registration of classes for dependency injection that we use in our solution. I.e. it doesn’t register the Sitecore classes that are accepted by the constructor for our ExmMailService service.
Great. Should I not be using that API, then? Only, it offers the functionality I need – I’m pretty sure it’s the right API. And I kind of think that a CM server should be able to act like a CD too.
However, in the configuration Sitecore.EmailExperience.ContentManagement.config they register a different set of services – not including the IClientApiService.
Not sure what the solution is yet, other than maybe adding an entry for the CD’s configurator too.