Xamarin.Forms中Autofac解析MainShell时抛出DependencyResolutionException
Let's break down why you're hitting that DependencyResolutionException when resolving MainShell—it almost always boils down to a missing or misconfigured dependency in your Autofac container. Here's how to diagnose and fix it:
1. First, Check the Inner Exception
The outer DependencyResolutionException is just a wrapper. The real clue is in the Inner Exception—it will tell you exactly which dependency Autofac can't resolve when trying to activate MainShell. For example, it might say something like "Unable to resolve parameter 'News2.MainViewModel vm' of constructor 'Void .ctor(News2.MainViewModel)'".
To see this, wrap your resolve call in a try-catch temporarily:
public App() { InitializeComponent(); Bootstrapper.Initialize(); try { MainPage = Resolver.Resolve<MainShell>(); } catch (Exception ex) { var rootCause = ex.InnerException; // Inspect rootCause.Message here (use debugger or print to console) } }
2. Verify MainShell's Constructor Dependencies
Chances are, your MainShell has a constructor that takes a ViewModel or another service, and that dependency isn't properly registered. For example:
// If your MainShell looks like this: public MainShell(MainViewModel mainViewModel) { InitializeComponent(); BindingContext = mainViewModel; }
You need to make sure MainViewModel is registered correctly in Autofac.
3. Fix ViewModel Registration Issues
Your current code scans for all ViewModel subclasses, but there are a few potential gaps here:
- Ensure your ViewModel actually inherits from
ViewModel: Double-check thatMainViewModel(or whatever dependency is missing) has: ViewModelin its class definition. - Add
.AsSelf()to your scan: By default, Autofac registers types as their concrete type, but explicitly adding.AsSelf()makes it clearer and avoids edge cases:containerBuilder.RegisterAssemblyTypes(typeof(App).Assembly) .Where(x => x.IsSubclassOf(typeof(ViewModel))) .AsSelf(); - Explicitly register problematic ViewModels (if needed): If scanning isn't picking up a ViewModel for some reason (e.g., it's in a different assembly), register it directly:
containerBuilder.RegisterType<MainViewModel>().AsSelf();
4. Check for Nested Dependencies
If your ViewModel has its own dependencies (like an API service), those also need to be registered. For example, if MainViewModel looks like this:
public MainViewModel(IArticleService articleService) { // ... }
You must register IArticleService and its implementation in Autofac:
containerBuilder.RegisterType<ArticleService>().As<IArticleService>();
Example Fixed Bootstrapper
Here's how your Bootstrapper might look after addressing these points:
public static class Bootstrapper { public static void Initialize() { var containerBuilder = new ContainerBuilder(); // Register services first (if any) containerBuilder.RegisterType<ArticleService>().As<IArticleService>(); // Register ViewModels (explicit + scan) containerBuilder.RegisterType<MainViewModel>().AsSelf(); containerBuilder.RegisterAssemblyTypes(typeof(App).Assembly) .Where(x => x.IsSubclassOf(typeof(ViewModel))) .AsSelf(); // Register MainShell containerBuilder.RegisterType<MainShell>(); var container = containerBuilder.Build(); Resolver.Initialize(container); } }
Final Notes
- Make sure all types you're trying to resolve are in the assembly you're scanning (
typeof(App).Assembly). If some are in a different project/assembly, add it to theRegisterAssemblyTypescall:containerBuilder.RegisterAssemblyTypes(typeof(App).Assembly, typeof(ViewModel).Assembly) .Where(x => x.IsSubclassOf(typeof(ViewModel))); - Avoid resolving types in constructors that might create circular dependencies (though that's less likely here with a Shell and ViewModel).
内容的提问来源于stack exchange,提问作者Jetmir

