Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simple Injector GetAllInstances throwing exception with Caliburn Micro

I have worked on Simple Injector and Caliburn micro but it's been a while almost 2 years. Now today when I tried to create a simple WPF application. First I end up reading the documentation as lot of changes has been done in both libraries.

I ran into couple of issues like "view can not be found" that get resolved later on but now I'm stuck with an strange issue. Tried enabling logger and everything but don't know if it's problem of Caliburn micro or of simple injector.

Here's my bootstrapper class:

 internal class AppBootstrapper : BootstrapperBase
    {
        public static readonly Container ContainerInstance = new Container();

        public AppBootstrapper()
        {
            LogManager.GetLog = type => new DebugLogger(type);
            Initialize();
        }

        protected override void Configure()
        {
            ContainerInstance.Register<IWindowManager, WindowManager>();
            ContainerInstance.RegisterSingleton<IEventAggregator, EventAggregator>();

            ContainerInstance.Register<MainWindowViewModel, MainWindowViewModel>();

            ContainerInstance.Verify();
        }

        protected override void OnStartup(object sender, System.Windows.StartupEventArgs e)
        {
            DisplayRootViewFor<MainWindowViewModel>();
        }

        protected override IEnumerable<object> GetAllInstances(Type service)
        {
            // This line throwing is exception when running the application
            // Error: 
            // ---> An exception of type 'SimpleInjector.ActivationException' occurred in SimpleInjector.dll
            // ---> Additional information: No registration for type IEnumerable<MainWindowView> could be found. 
            // ---> No registration for type IEnumerable<MainWindowView> could be found. 
            return ContainerInstance.GetAllInstances(service);
        }

        protected override object GetInstance(System.Type service, string key)
        {
            return ContainerInstance.GetInstance(service);
        }

        protected override IEnumerable<Assembly> SelectAssemblies()
        {
            return new[] {
                    Assembly.GetExecutingAssembly()
                };
        }

        protected override void BuildUp(object instance)
        {
            var registration = ContainerInstance.GetRegistration(instance.GetType(), true);
            registration.Registration.InitializeInstance(instance);
        }
    }

Not sure what am I missing here?

like image 990
vendettamit Avatar asked Feb 09 '23 04:02

vendettamit


1 Answers

Simple Injector v3 contains several breaking changes. The one you are troubled by is the breaking change of issue #98. By default, Simple Injector v3 will not resolve unregistered collections as empty collections anymore. As you've noticed, this breaks the adapter for Caliburn.

To fix this, you will have to change the GetAllInstances method to the following:

protected override IEnumerable<object> GetAllInstances(Type service)
{
    IServiceProvider provider = ContainerInstance;
    Type collectionType = typeof(IEnumerable<>).MakeGenericType(service);
    var services = (IEnumerable<object>)provider.GetService(collectionType);
    return services ?? Enumerable.Empty<object>();
}
like image 57
Steven Avatar answered Feb 11 '23 18:02

Steven