Base solution for your next web application
Open Closed

Calling AppServices Via Plugin #12137


User avatar
0
mittera created

Do you have a example of an aspnetzero plugin that can reference Application.Shared dll for interfaces and load the service di dependency injection for use in the plugin?

I have been working on this, and it compiles, and i can step thru the plugin logic. In the constructor i use dependency injection to populate the private readonly service property.

In my plugin method i can display the service property and it successfully populated, but if I step into a method on the service property, the application returns from my method without calling the app service method or any code after it. It appears if something is hiding an exception as no error's are produced. I have tried this with my own appservices and the out of the box tenantAppService and same results. If i use the repos directly without going thru the app service it works as well. But i would rather use the app service to ensure no code duplication from having some code targeting repos and some targeting services....

Any ideas you have on what the issue could be would be helpful, but an example plugin project would be amazing!

The application is Using AspNet Core Angular 13.2

Below is a simple example of the issue.


5 Answer(s)
  • User Avatar
    0
    m.aliozkaya created
    Support Team

    Hi @mittera,

    If you share the logs from the application, we may find the error. The application service methods in the plugin must work successfully.

    This is a modular monolith example. However, the structure is similar to the plugin system. https://github.com/aspnetzero/aspnet-zero-samples/tree/master/ModularMonolithMvcDemo

    Also the documentation https://aspnetboilerplate.com/Pages/Documents/Plugin

  • User Avatar
    0
    mittera created

    Hi @mittera,

    If you share the logs from the application, we may find the error. The application service methods in the plugin must work successfully.

    This is a modular monolith example. However, the structure is similar to the plugin system. https://github.com/aspnetzero/aspnet-zero-samples/tree/master/ModularMonolithMvcDemo

    Also the documentation https://aspnetboilerplate.com/Pages/Documents/Plugin

    The second link is the documentation i used to build this and and using the repos it works.

    Tonight i took a short break while debugging this and when i came back it worked via the app service.

    The issue was timing, if i fire the the app service method before the app service is initialized the method does a return on the function. No error is logged. I would expect service not found or something...

    So I guess the root question is when loading a plugin that calls an app service during the plugins post Init, how can i ensure the app service is loaded before attempting to call the service method? The depends on seems like the obvious choice, but then do i need my plugin to reference the application dll so it can depend on the module? i don't want to do this as I am referencing all the services via IServiceNameAppSerivce and have no other reliance on it. Currently i am only depending on "BaseAppCoreModule" and that is why the repos work... Can i set the dependency on an interface instead of a module? Thanks in advance for any help you can provide.

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi @mittera

    If I understand correctly, you want to call one of the AppServices via your plugin, is that right ? If so, Plugins are not designed to work that way. As you faced, there might be unexpected problems.

    Maybe, instead of using AppServices, you can create a shared project (which contains the implementation) and use it in your PlugIn and Application.

    Ideally, Plugins shouldn't be aware of your main application.

  • User Avatar
    0
    mittera created

    I would agree that moving the app services that are to have shared access to a separate library it the best practice approach, but for a plugin based application, this provides some difficulty for me. I am wanting the plugin system to be able to access all app code in the future without needed the app code to be modified or moved to a library. This way you develop the main app as normal, and the plugins can access all the code when they are created / needed.

    I was planning on using unique interfaces for all app services like ASPNetzero uses out of the box, and dependency injection based on the interface to load the class at runtime. Using this i was able to create two plugins that compile and were tested. They would load, but would fail loading dependencies in the constructor if the dependent object wan not loaded yet.

    Normally this would be fixed with the depends on attribute of the plugin. But those target the dependent class and not interface, and will not work without adding a actual reference to the dependent library for the class.

    I was able to get it working with using the event bus trigger in AppServicesModule's post-init method to tell the host when it is loaded. During startup I moved the plugin load code to be inside of a event bus listener that when triggered after the AppServicesModule is loaded.

    This way all parts of the base system are loaded before the plugin system loads. This is still in development, but seems to be working perfectly, and doesn't feel like there is any lag in the startup either.

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi @mittera

    Thanks for sharing your solution :) I hope it will not cause any issues in the future.