JasperFx / lamar

Fast Inversion of Control Tool and Successor to StructureMap
https://jasperfx.github.io/lamar
MIT License
573 stars 119 forks source link

Request for optimized Blazor Assembly and lazy loading with modules #315

Closed lolochristen closed 2 years ago

lolochristen commented 2 years ago

We have the intention to use Lamar with Wasm Blazor Apps especially in combination with Lazy Loading of libraries in Blazor (https://docs.microsoft.com/en-us/aspnet/core/blazor/webassembly-lazy-load-assemblies?view=aspnetcore-6.0). Lazy loading introduces the problem of properly extending the DI container with new types of the loaded assembly. As the default DI container does not support adding new types, especially scoped types, and also other famous DI like AutoFac, etc have removed or not support this capability, Lamar seems the only player who supports this. Great work! I fully understand the risk of modifying the container, but we intend only to extend with new types. Using Lamar in this scenario brings up the following request:

  1. Lamar.Microsoft.DependencyInjection references Microsoft.AspNetCore.* assembly which are not required in a Blazor scenario and just blow up the the client. Any change to split LamarServiceProviderFactory and the WebHostBuilderExtensions into separate assemblies?
  2. Lazy loading requires also a dynamic way to register types. Can you introduce a feature to load and assembly and its types into a container/service registry similar to AutoFac's Modules approach? It must be callable after the building process too to support dynamic loading. We have an implementation doing this (using interface IModule using reflection) but we would prefer it as an official feature as this could benefit others.

thanks!

jeremydmiller commented 2 years ago

@lolochristen I don't use Blazor and don't have the slightest clue how to even go about that. And I really, really don't recommend folks use Lamar's ability to re-configure the container after it's initially built out. That Container.Configure() method is an historical accident to slide around some kind of early ASP.Net Core weirdness. So Caveat Emptor on that one.

As for something in Lamar like AutoFac's "Modules", Lamar is descended from StructureMap which predates Autofac by several years, so I'm gonna turn that around and say that AutoFac's Modules are somewhat like StructureMap/Lamar's Registry/ServiceRegistry model and Lamar has strong support for automatic type discovery which you can find in the docs.

"Lamar.Microsoft.DependencyInjection references Microsoft.AspNetCore.* assembly which are not required in a Blazor scenario and just blow up the the client. Any change to split LamarServiceProviderFactory and the WebHostBuilderExtensions into separate assemblies?" -- I really don't want to deal with that. I'd vote for a separate assembly for Blazor that includes only what you need rather than destabilizing the existing ecosystem. You'd have to expose ServiceRegistry rather than IServiceCollection in the Configure() method. I'm not enthusiastic about that because it's a heaping ball of new complexity. What if someone adds a new policy that impacts existing registrations? What if there are overrides?

Long winded way of saying it's just not completely that simple.

lolochristen commented 2 years ago

Thanks for your feedback. the ServiceRegistry replaces indeed any module like construct. Also, the registration of Lamar in Blazor client to avoid AspNetCore Libs could be extracted easily. So far I can say, Lamar works smoothly also in Blazor WASMs. About Container.Configure(), I am fully aware of the risks and potential side effects. But it's currently your USP.

jan-johansson-mr commented 1 year ago

Hi @lolochristen and @jeremydmiller Was reading this, and I'm pleased that Container.Configure(...) is still alive and kicking. The stuff with lazy loading into an environment do require some magic to happen, to integrate the loaded parts into the environment. The alternative is to provide patterns and conventions, that can be hard to maintain. The Configure provides one such magic piece. As you say @lolochristen, this is an USP, without it, lamar becomes YADI (yet another DI) on the stack.