YairHalberstadt / stronginject

compile time dependency injection for .NET
MIT License
845 stars 24 forks source link

Include full dependency chain in error message #127

Open trampster opened 3 years ago

trampster commented 3 years ago

I have have an error as follows:

Error while resolving dependencies for 'Pttox.Core.ViewModels.GroupPttViewModel': We have no source for instance of type 'Xamarin.Forms.Page?'

GroupPttViewModel doesn't have a direct dependency on Page, and GroupPttViewModel's depedency tree is quite large so finding the things that needs Page is hard.

Searching the code for Page is hopeless because it's a Xamarin.Forms app so page is everywhere.

Would it be possible to make the error message include the full dependency chain, or at least include the type that has a direct dependency on Page.

trampster commented 3 years ago

I just had another one.

Error while resolving dependencies for 'Pttox.Forms.Views.AppShell': We have no source for instance of type 'UIKit.UIViewController'

This is particularly confusing, as I only have a handful of iOS specific services and none of them have a dependency on UIKit.UIViewController, in fact the text UIViewController doesn't exist anywhere in my solution.

Pttox.Forms.Views.AppShell is defined in the shared project

Here are a list of the types registered in my iOS module

I have the following factory

YairHalberstadt commented 3 years ago

So I do actually include the whole message in the diagnostic - as a description, which unfortunately visual studio doesn't display:

https://github.com/dotnet/roslyn/discussions/46911

I could move it out of the description, but that would make the messages way too long I think. Perhaps I could add an MS build property to show full path.

trampster commented 3 years ago

Is there anyway for me to get at this diagnostic info? It doesn't seem to be in the output info under Build.

I also tried changing the 'MSBuild project build output verbosity' to 'Diagnostic' but that didn't work either.

YairHalberstadt commented 3 years ago

At the moment I don't think so (other than compiling the project using Roslyn directly and accessing the diagnostic). If the diagnostic appears in intellisense (which another Roslyn bug prevents) you can expand it in visual studio, but not if it comes from build.

trampster commented 3 years ago

I think that UIKit.UIViewController is used internally by Xamarin.Forms to render a page on iOS. In our app AppShell is responsible for getting and displaying the Xamarin.Forms pages.

So it is probably trying to create a Xamarin.Forms view and somehow StrongInject has been fooled into trying to resolve UIViewController I'll try and create a minimal Xamarin.Forms. iOS project to demonstrate the problem.

trampster commented 3 years ago

I finally managed to track down the UIViewController dependency issue (by removing dependencies until it started working)

We use a barcode scanner library called ZXing.Mobile. It has an interface IMobileBarcodeScanner which needs to be resolved to MobileBarcodeScanner. In the shared .Net standard project this only has a default constructor but in an iOS project it has a constructor taking a UIViewController. (I assume this is using the old bait a switch cross platform method)

So when I build the iOS project it tries to resolve using the constructor that takes a UIViewController. Even through that constructor does not exist in the shared project in which it is registered.

I have worked around this issue by defining a Factory which calls the default constructor.