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

DependencyInjection with MvcPluginLoader #52

Open
martijnmelchers opened this issue Sep 9, 2021 · 4 comments
Open

DependencyInjection with MvcPluginLoader #52

martijnmelchers opened this issue Sep 9, 2021 · 4 comments

Comments

@martijnmelchers
Copy link

Hi,

First off nice library, second of all I'm trying to get the Prise.Mvc to work with Dependency Injection. I got it to work when when loading the plugins in ConfigureServices however when I move it to Configure it can't initialize the plugin.

This is my code for activating the plugins:

           using (var scope = services.BuildServiceProvider().CreateScope())
            {
                var pathService = scope.ServiceProvider.GetRequiredService<IPathService>();
                var mvcPluginLoader = scope.ServiceProvider.GetRequiredService<IMvcPluginLoader>();
                var pluginLoader = scope.ServiceProvider.GetRequiredService<IPluginLoader>();
                var builder = scope.ServiceProvider.GetRequiredService<ApplicationPartManager>();


                var plugins = await mvcPluginLoader.FindPlugins<IPluginMvc>(pathService.GetPluginPath());

                foreach (var assemblyScanResult in plugins)
                {
                    Console.WriteLine(assemblyScanResult.ContractType);

                    var plugin = await mvcPluginLoader.LoadPluginAssembly<IPluginMvc>(assemblyScanResult);
                    builder.ApplicationParts.Add(new PluginAssemblyPart(plugin.Assembly));
                }
            }

And this is my controller in the plugin:

public class TestController : ControllerBase
    {
        private readonly ILogger<TestController> _logger;
        private readonly IPathService _pathService;

        public TestController(ILogger<TestController> logger, IPathService pathService)
        {
            _logger = logger;
            _pathService = pathService;
        }

        [HttpGet("Test")]
        public IActionResult Test()
        {
            _logger.LogInformation("Test called!");
            return Ok(_pathService.GetPluginPath());
        }
    }

I'm using the latest version of the plugin and .NET 5.0

@merken
Copy link
Owner

merken commented Sep 10, 2021

Hi Martijn,

Have you looked at the example (Example.Mvc.Razor) https://github.com/merken/Prise/blob/master/samples/Example.Mvc.Razor/Controllers/HomeController.cs ?

All service registration should be done in the ConfigureServices method in .NET, not sure why you'd move that to the Configure method (this is mainly for App configuration, not services)

https://github.com/merken/Prise/blob/master/samples/Example.Mvc.Razor/Startup.cs#L31

@martijnmelchers
Copy link
Author

martijnmelchers commented Sep 10, 2021

Thanks. I've looked at the code provided however I want to enable these plugins as soon as the application boots. Which is why I am doing it in ConfigureServices however it's not recommended to ues BuildServiceProvider() inside of ConfigureServices hence why I wanted to move it to Configure

However when the plugins are booted in ConfigureServices the controllers correctly construct with DepedencyInjecten but if it's called in Configure() it is not.

@martijnmelchers
Copy link
Author

Also when I followed the example code in the repository this error occurs when trying to go to the route:

Prise.Activation.PluginActivationException: Plugin of type TestController could not be activated.
   at Prise.Activation.DefaultRemotePluginActivator.CreateRemoteInstance(IPluginActivationContext pluginActivationContext, IPluginBootstrapper bootstrapper, IServiceCollection hostServices)
   at Prise.Mvc.DefaultPriseMvcControllerActivator.Create(ControllerContext context)
   at Microsoft.AspNetCore.Mvc.Controllers.ControllerFactoryProvider.<>c__DisplayClass5_0.<CreateControllerFactory>g__CreateController|0(ControllerContext controllerContext)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()
--- End of stack trace from previous location ---
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
   at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

However when loaded in ConfigureServices it works perfectly fine.

@merken
Copy link
Owner

merken commented Oct 4, 2022

Hi Martijn,

Please provide a reproduction repo for this.

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

No branches or pull requests

2 participants