Re-Registering every service for WebAPI (net45)?

Sep 26, 2013 at 11:05 PM
Please help... not exactly sure what's wrong if anything.. but in all of the examples and documentation I didn't see anything that required registering every default implementation of each service for WebAPI like I'm doing..

background/possibly pertinent?:
-using Bootstrapper generic registrations to abstract out SimpleInjector specifics from my entry assembly (webAPI project)...
-I have a DependencyResolution project (like in the OnionArchitecture project mentioned in another discussion posting here).
-I'm using OutputTo nuget to copy over all assemblies referenced in dependencyResolution project to the WebAPI project's bin.

What I'm doing just feels dirty... doesn't the GlobalConfiguration.Services methods use ServiceLocator abstraction to resolve types??
public class RegisterMyTypes : IBootstrapperRegistration
    {
        public void Register(IBootstrapperContainerExtension pContainerExtension)
        {
            pContainerExtension.Register<IApiExplorer>((ApiExplorer) GlobalConfiguration.Configuration.Services.GetApiExplorer());
            pContainerExtension.Register<IHttpControllerSelector>(GlobalConfiguration.Configuration.Services.GetHttpControllerSelector());
            pContainerExtension.Register<IAssembliesResolver>(GlobalConfiguration.Configuration.Services.GetAssembliesResolver());
            pContainerExtension.Register<IHttpControllerTypeResolver>(GlobalConfiguration.Configuration.Services.GetHttpControllerTypeResolver());
            pContainerExtension.Register<IHttpActionSelector>(GlobalConfiguration.Configuration.Services.GetActionSelector());
            pContainerExtension.Register(GlobalConfiguration.Configuration.Services.GetModelMetadataProvider());
            pContainerExtension.Register(GlobalConfiguration.Configuration.Services.GetTraceManager());
            pContainerExtension.Register(GlobalConfiguration.Configuration.Services.GetTraceWriter());
            pContainerExtension.Register(GlobalConfiguration.Configuration.Services.GetActionInvoker());
            pContainerExtension.Register(GlobalConfiguration.Configuration.Services.GetActionValueBinder());
            pContainerExtension.Register(GlobalConfiguration.Configuration.Services.GetContentNegotiator());

        }
    }
Sep 26, 2013 at 11:30 PM
Edited Sep 26, 2013 at 11:37 PM
BTW, this is working... after adding re-registering a few other services... But it can't be right...

my Bootstrapper start code is:
Bootstrapper.With
                        .ConfigureIoC()
                        .And.ServiceLocator()
                        .LookForTypesIn.LoadedAssemblies()
                        .Start();
Doesnt using And.ServiceLocator() extension register SimpleInjector implementations for ServiceLocator resolve methods? Seems like I also did not have to register any controller types with SimpleInjector either. I'm not sure why that is... thoughts?
Coordinator
Sep 26, 2013 at 11:52 PM
Hi dieghohb.
I have to confess I'm not super familiar with WebAPI, so my help here could be limited. However, I am curious about how your ConfigureIOC method looks. Could I take a peek?

Thanks

Luis
Sep 27, 2013 at 12:16 AM
sure..
/// <summary>
    /// This should abstract away any specifics about which IoC container framework was used.
    /// </summary>
    /// <remarks>The entry-point assembly will initialize Bootstrapper as usual and simply call ConfigureIoC().</remarks>
    public static class IoCBootstrapperExtensions
    {
        public static IBootstrapperOption ConfigureIoC(this BootstrapperExtensions pExtensions, IEnumerable<Type> pInitialTypesToRegister = null)
        {
            var container = new Container();
            container.Options.ConstructorResolutionBehavior = new MostResolvableConstructorBehavior(container);

            if (pInitialTypesToRegister != null)
            {
                foreach (var concreteType in pInitialTypesToRegister)
                {
                    container.Register(concreteType);
                }
            }

            return pExtensions.SimpleInjector().WithContainer(container);
        }
}
Then I implement ISimpleInjectorRegistration to wire up all of my repositories, services, etc. And in the web project i implement IBootstrapperRegistration to use Bootstrapper generic registration to register all MVC stuff... which apparently is EVERYTHING originally wired up by ServiceLocator abstraction (GlobalConfiguration.Configuration.Services).

My goal is to NOT reference/install nuget for SimpleInjector or related libraries in the entry application (MVC WebAPI project in this case)...
Sep 27, 2013 at 12:20 AM
And now after registering everything possible... I am finding that when trying to access one of my actions with parameters (works without passing parameters), i get the error:
"No registration for type IModelValidatorCache could be found."
.... that interface (and its implementation) is INTERNAL to .NET Http assembly.... so this can't be the right way to do this.
Sep 27, 2013 at 2:50 AM
I got it to work without setting the dependencyresolver at all... instead i did:
GlobalConfiguration.Configuration.Services.Replace(typeof (IHttpControllerActivator), new BootstrapperControllerActivator());
public class BootstrapperControllerActivator : IHttpControllerActivator
    {
        public IHttpController Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)
        {
            return (IHttpController) Bootstrapper.ContainerExtension.Resolve(controllerType);
        }
    }
I imagine this means that only controller dependencies will be injected (instead of all of the services I listed above)... so I'm still wondering how to make the dependencyresolver work.