0

I'm a bit lost here. I am trying to set up a very simple app with Prism.Autofac.Wpf 7;

App.xaml.cs:

public partial class App
{
    protected override Window CreateShell()
    {
        return Container.Resolve<MainWindow>(); // this point won't even be reached
    }

    protected override void RegisterTypes(IContainerRegistry containerRegistry)
    {
    }

    protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog)
    {
        base.ConfigureModuleCatalog(moduleCatalog);
    }
}

App.xaml:

<prism:PrismApplication x:Class="MyNamespace.App"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:prism="http://prismlibrary.com/"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
</prism:PrismApplication>

upon startup, this throws a DependencyResolutionException at some point after RegisterTypes() has been called, but before CreateShell() is called:

None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type   'Prism.Autofac.AutofacServiceLocatorAdapter' can be invoked with the available services and parameters:
Cannot resolve parameter 'Autofac.IContainer container' of constructor 'Void .ctor(Autofac.IContainer)'.

at Autofac.Core.Activators.Reflection.ReflectionActivator.GetValidConstructorBindings(IComponentContext context, IEnumerable`1 parameters)
at Autofac.Core.Activators.Reflection.ReflectionActivator.ActivateInstance(IComponentContext context, IEnumerable`1 parameters)
at Autofac.Core.Resolving.InstanceLookup.Activate(IEnumerable`1 parameters)

Naively going by the error message and trying to register the IContainer myself, I have tried

    protected override void RegisterTypes(IContainerRegistry containerRegistry)
    {
        var builder = containerRegistry.GetBuilder();
        // .. register a few modules here ..

        var container = builder.Build();
        containerRegistry.RegisterInstance<IContainer>(container);
    }

but then I'll get an InvalidOperationException: "Build() or Update() can only be called once on a ContainerBuilder."

I'm a bit lost here - what's going wrong in this minimal example?!

Thanks

Bogey
  • 4,926
  • 4
  • 32
  • 57
  • This should be fixed in the latest CI build. Give it a try and let us know if you have any issues in the Prism GitHub site –  Mar 01 '18 at 03:05

2 Answers2

0

There is no Prism v7 for WPF yet. So you must be using the CI builds, or possibly the preview. Having said that, you can't call Build(). Prism calls this when the initialization of the app has completed. Autofac is an immutable container meaning once you call Build() you can no longer register anything with the container.

0

First building the container yourself will lead to bad things. Also due to Autofac deprecating the Builder.Update, we now ensure that you have the same builder that Prism is using behind the scenes. When you call builder.Build(), you cannot then register the resulting IContainer with the ContainerRegistry, because you built the Builder... Second Autofac is immutable due to that deprecation which is why we no longer can support Modules with Autofac.

With the new Prism 7 IOC interfaces, you should try injecting IContainerProvider. This will allow you to resolve what you need.... assuming here you have a good reason for doing that....

Lastly I should point out Autofac purposefully doesn’t resolve IContainer, you should instead be resolving IComponentContext or ILifetimeScope if you need an Autofac specific interface for some reason. You can read more about that here.

Dan Siegel
  • 5,724
  • 2
  • 14
  • 28
  • Thanks Dan, Dan it helpful. However, I should point out I haven't really used anything except for the snippet above - meaning, the request for an IContainer must have beem from a class that ships with the current Prism-related libraries (or possibly from CommonServiceLocation?) – Bogey Jan 24 '18 at 15:57
  • Then that sounds like a bug – Dan Siegel Jan 24 '18 at 15:59