Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace MvxIoCProvider with Microsoft.Extensions.DependencyInjection #4436

Open
3 tasks
Cheesebaron opened this issue Jul 14, 2022 · 8 comments
Open
3 tasks

Comments

@Cheesebaron
Copy link
Member

Cheesebaron commented Jul 14, 2022

We often get requests to improve the feature set of the IoC Provider we have in MvvmCross. In order to not reinvent the wheels every time, we should switch to Microsoft.Extensions.DependencyInjection.Abstractions and let the users chose any of the supported IoC Providers it supports, which provides the functionality.

This way we can let the consumer chose whether to use AutoFac, Ninject, MS.Extensions.DI or whatever IoC Provider they chose.

  • Remove IMvxIoCProvider
  • Remove MvxSingleton
  • Think about whether to keep the Plugin structure for MvvmCross or let users manage registrations for similar functionality themselves
@entdark
Copy link
Contributor

entdark commented Jul 15, 2022

As I said in VM issue, let MvvmCross add extra functionality, not replace. So basically leave its own implementation with a possibility to replace it.

@DuncanMT
Copy link

@entdark That would be ideal yes, however, due to the nature of the MvvmCross Xamarin.Forms startup implementation detail in MvvmCross requiring the ability to resolve components part way through the setup process, and then continue registering more components, the MvvmCross startup system is completely incompatible with MS.Extensions.DI which requires all components to be registered before .Build() is called.

In the solution, I've been working with recently in order to leverage the HttpClient and EFCore, IConfiguration and IOptions packages from Microsoft I've resorted to building a MS.DI service collection and then translating the container services into the MvvmCross IMvxIoCProvider instance. There are many incompatibilities and drawbacks with this approach, the least of which being the 2 stage startup process, but it was deemed an acceptable short-term cost in order to be able to fully leverage Microsoft.Extensions.

For a cursory glance at the Autofac docs it appears that that container option is in a similar situation with a .Build() method call.

Is there any appetite from others for a PR to alter the startup process in order to support the "Configure Once -> Build -> Resolve" pattern for the IoC? I'd imagine that it would be a hefty chunk of work, and potentially incompatible with the MvvmCross plugin system.

@Cheesebaron
Copy link
Member Author

I don't find much value in the plugin system anymore. Most of the plugins have been replaced by Xamarin.Essentials or the likes. The only nice thing is that they are auto discovered and registered, which could be done through Source Generators instead or relfection for better performance.

But yes, fixing the startup to only configure once is a bit of a job, and would sacrifice some things. However, it would make it much easier to set up MvvmCross and integrate with other startup processes.

@ErisApps
Copy link
Contributor

ErisApps commented Aug 9, 2023

@Cheesebaron out of curiosity, what's the current plan regarding this?

@Cheesebaron
Copy link
Member Author

Cheesebaron commented Aug 9, 2023

@ErisApps I did a spike on adding trimmer annotations to the code last week. Turns out Mvx.IoCProvider seeps into a lot of places. You can see some of it here: https://github.com/MvvmCross/MvvmCross/commits/feature/dynamically-accessed-members

Also did a spike on creating an AppHost, where I also switched to MEDI. But a bit in doubt whether I still want to do MEDI or run with something like Jab or Pure.DI, which is compile time generated dependencies.

Perhaps MvvmCross should just provide an Interface developers need to implement, to get dependencies from a container and provide Extension methods for common containers to register itself. I am still experimenting when I have time.

Regardless, it is a lot of work to replace.

@ErisApps
Copy link
Contributor

ErisApps commented Aug 9, 2023

First of all, thank you for your response (and in extend also your continued contributions to MvvmCross).

In my humble opinion, I'd most likely still opt for MEDI regardless. The main selling point of MEDI(.Abstractions) mostly comes from the fact that other library authors being able to just develop against a common set of interfaces, making it a lot easier to tell consumers that they have to call a specific extension method on their IServiceCollection, not having to worry about what the underlying DI container is.
As a nice addition, it also makes it easier to share the same library between a client and backend/microservice for example.

Obviously not my intention to state that looking at others containers should not be done, but mainly wanted to imply as well that relying on MEDI and something like Pure.DI isn't exactly mutually exclusive either. 🙂

@Cheesebaron
Copy link
Member Author

MEDI is also what I am leaning towards the most as well. Just need to ensure that all the reflection and traversing assemblies we do need to be done at compile time instead of at runtime.
I guess I need to learn some more about source generators. Fun!

@ErisApps
Copy link
Contributor

ErisApps commented Aug 9, 2023

Getting rid of all reflection and traversing assembly isn't exactly a strict requirement to adopt MEDI (if I'm not mistaken), but I agree it would definitely help in the case for trimming safety, and in extension for NativeAOT.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

4 participants