question

SkyS-3413 avatar image
0 Votes"
SkyS-3413 asked SkyS-3413 commented

Asp.Net Core: Have to find a way to dynamically register EDM & ODataControllers *after* app.build event()

Hi,

We're in a bit of a (real) bind.

We need to demonstrate to stakeholders that Asp.Net Core stack is still a viable platform for this project which MUST loading plugins containing an set of WebAPI and OData Controllers unknown at startup. Due to our lack of success so far everybody is getting jumpy.

Specifically:
- one solution, one project
- with 2 ODataControllers,
- One Convention based EDM model registered during startup, pointing to only one of the two ODataControllers
- such that when invoked (ie way after Build),
- registers a second EDM model that points to the second ODataController.
- proving:
- ODataControllers can be registered late (as if they had just been made available via a plugin)

We have not envisioned yet know how to prove the same with two simple WebAPI (not OData) Controllers -- as they are automatically spotted/found/registered at startup.

For bonus points, if anyone knows any/elegant? way to register Services late (eg: those that came in via the Plugin)...but I think StackOverflow is littered with that question, and no straight forward answers.


Thank you!

dotnet-aspnet-core-webapi
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

1 Answer

Bruce-SqlWork avatar image
0 Votes"
Bruce-SqlWork answered SkyS-3413 commented

your goal is not clear. controllers are already a plugin model. you just publish to the bin folder and restart.

if you need dynamic loading and routing then:

to implement true plugins see:

https://learn.microsoft.com/en-us/dotnet/core/tutorials/creating-app-with-plugin-support

you would have a master controller that called the proper plugin.

for dynamic routing see:

https://medium.com/@fedonman/dynamic-controller-routing-in-asp-net-5-ac81a6bb8a95

· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Hi Bruce,
Thank you for responding.

Apologies that the question was not clear.

Dynamic plugins means that plugins can be uploaded/removed without restarting the application (I might call the second approach simply modular development).

Agreed: the use of a AssemblyLoadContext is the Asp.Net Core equivalent of AppDomain and a starting point to plugin development.

But without restarting, the framework doesn't go back through the process of re-discovering its potential controllers.

As per
https://stackoverflow.com/questions/46156649/asp-net-core-register-controller-at-runtime
The first piece of the puzzle is to use a custom instance of IActionDescriptorChangeProvider

That is only the first tiny piece of the puzzle.
The second aspect is that a plugin's Controllers may require custom Services.
The issue is that IServiceCollection and IServiceProvider are both locked down at that late stage.

The only way (so far) I've found to late register Services is to use Autofac's child lifetime scopes.
And holding references to them as the basis of a IControllerActivator to instantiate Controllers (trying the default IServiceProvider..and failing that trying to find the right module ILifetimescope to instantate the controller and its service).

OData adds a twist to the issue. Whereas ODataControllers are Controllers, and therefore solved above, they ALSO require the registration of an EDM model. This process of EDM model registration is done at startup. And needs to be replicated at plugin load time. That's the last(?) missing piece.


0 Votes 0 ·