Debugging

May 21, 2013 at 5:28 PM
I have the following Bootstrapper configuration:
Bootstrapper.IncludingOnly
                .Assembly(Assembly.GetAssembly(typeof(App)))
                .AndAssembly(Assembly.GetAssembly(typeof(Adapter)))
                .With.SimpleInjector()
                .And.ServiceLocator()
                .And.AutoMapper()
                .And.StartupTasks()
                .UsingThisExecutionOrder(s => s
                    .First<RegionAdapterMappingsTask>()
                    .Then<RegionBehaviorTask>()
                    .Then<FrameworkExceptionTask>()
                    .Then<ShellTask>()
                    .Then<InitializeModulesTask>())
                .Start();
However, I set breakpoint in the ISimpleInjectorRegistration class that I've implemented, and it is not passing there. Also none of the Task are being called. How can I debug to see what's wrong?
Coordinator
May 21, 2013 at 5:44 PM
Is it possible that your registration class is in an assembly other than the one that contains App and Adapter?
You could try removing the IncludingOnly part to see if it works.
May 21, 2013 at 6:07 PM
The problem was the my classes are internal. I changed to public and bootstrapper found them.
Another problem that I'm facing is regarding the IServiceLocator:
public class RegionAdapterMappingsTask : IStartupTask
    {
        private readonly RegionAdapterMappings regionAdapterMappings;
        private readonly IServiceLocator serviceLocator;

        public RegionAdapterMappingsTask(RegionAdapterMappings regionAdapterMappings, IServiceLocator serviceLocator)
        {
            this.regionAdapterMappings = regionAdapterMappings;
            this.serviceLocator = serviceLocator;
        }

        public void Reset()
        {
        }

        public void Run()
        {
            regionAdapterMappings.RegisterMapping(typeof(Selector), serviceLocator.GetInstance<SelectorRegionAdapter>());
            regionAdapterMappings.RegisterMapping(typeof(ItemsControl), serviceLocator.GetInstance<ItemsControlRegionAdapter>());
            regionAdapterMappings.RegisterMapping(typeof(ContentControl), serviceLocator.GetInstance<ContentControlRegionAdapter>());
        }
    }
In this Task, I need the IServiceLocator, but it gives me this error:

____The registered delegate for type RegionAdapterMappingsTask threw an exception. No registration for type RegionAdapterMappingsTask could be found and an implicit registration could not be made. The constructor of the type RegionAdapterMappingsTask contains the parameter of type IServiceLocator with name 'serviceLocator' that is not registered. Please ensure IServiceLocator is registered in the container, or change the constructor of RegionAdapterMappingsTask.

But you can see that I'm using And.ServiceLocator() extension
Coordinator
May 21, 2013 at 6:21 PM
Service Locator get set but not registered in the container.
You have two options
1) Use the static class ServiceLocator.Current
2) Create a registration for IServiceLocator so you can get it injected.

Hope that helps.
May 21, 2013 at 6:29 PM
Edited May 21, 2013 at 7:06 PM
I think it should be registered in the container by default.
It's bad design to use ServiceLocator itself, but I think is "more bad" (sorry for this expression) to use the static ServiceLocator. Using the interface IServiceLocator is better, so it should be registered in the container.
Also, I'm using PRISM framework for WPF and it requires the IServiceLocator to be registered; I can't simple use static ServiceLocator because I have no access to the framework code.

Nonetheless, how should I register the ServiceLocator?
Tried:
Bootstrapper.IncludingOnly
                .Assembly(Assembly.GetAssembly(typeof(App)))
                .AndAssembly(Assembly.GetAssembly(typeof(Adapter)))
                .With.SimpleInjector()
                .And.ServiceLocator();
            var container = (Container)Bootstrapper.Container;
            container.RegisterSingle<IServiceLocator>(ServiceLocator.Current);
            Bootstrapper.With
                .And.AutoMapper()
                .And.StartupTasks()
                .UsingThisExecutionOrder(s => s
                    .First<RegionAdapterMappingsTask>()
                    .Then<RegionBehaviorTask>()
                    .Then<FrameworkExceptionTask>()
                    .Then<ShellTask>()
                    .Then<InitializeModulesTask>())
                .Start();
Coordinator
May 21, 2013 at 8:24 PM
I am not super familiar with SimpleInjector and I don't have time to try it now, but you could try adding a class like this:
public class ServiceLocatorRegistration: ISimpleInjectorRegistration
    {
        public void Register(Container container)
        {
            container.RegisterSingle<IServiceLocator>(() => ServiceLocator.Current);
        }
    }
May 21, 2013 at 10:05 PM
That will do it... thanks