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.
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.
I am using 3.3.0
I have attached the entity json files to this link.
I notice the experience when I build Workflow, Workflow Symbol, ProductionOutput, WorkflowProperty, WorkflowSymbolProperty
Then try to rebuild the Workflow one again if you can even get this far before it has the issue.
Not 100% consistent, but it is persistently present.
In the application I am working on I have entity "A", "B", and "C".
"A" is a menu item with "B" as a master detail. "B is also on the menu with "C" as a master detail
If I regenerate in this order C, B, A it all works.
Then I can regenerate "A" without issue multiple times.
Then if I regenerate "B", it still works.
But then If I try to regenerate "A" again it will fail, with the JSON issue listed above.
So not sure it it is the three tired relationship, or just that it was built as both a master and a detail...
But after fixing the JSON I can regenerate "A" again...
Hope this additional information helps.
I can provide them but it requires a couple entity json files to make it happen as it only happens with Master Detail pages.
How do i go about getting you these files? Do I just a attach them here, or is there a better method?
The problem seems to happen randomly, or at least I haven't figured out the trigger yet.
But it usually happens when regenerating an entity that has at least one master detail property.
The build for the primary entity builds then it automatically tries to rebuild the foreign object.
This logs that it is starting in the console, but then just sits there, I have waited 30 minutes, and nothing.
So I cancel the generation, and rerun it, but now the primary entity will not even start...
In review of the json entity files, the primary entity and the foreign entity files have the same timestamp.
This is also the same time of the first failed execution. So both files were updated during the execution.
Nothing looks different in the primary entity file, but the foreign entity file is different with the navigation property looking like the image I sent in creating this ticket.
So I update the navigation property to move the "IsGeneratedbyMasterPage" to where it should be and save the file.
I then can then regenerate the primary entity again, and the foreign entity auto generates as well.
The problem is, Power Tools is reading in valid json using it and then replacing it with invalid json.
The other thing to note, is that once the invalid file is fixed, by simply moving the "IsGeneratedbyMasterPage" property, the fixed file is i identical to the original input file. So Power Tools over wrote it but was not intending to even make any changes..
This makes me wonder is there a way to ensure the entity json files are not auto updated during generation process, especially if the content is not changing.........
Thank you that would be great!
Just to pass along an Idea....
What about switching from the optional use of the duplication number on navigation properties and master details to just always using the foreign key property name?
The duplication number is a good idea, but is not working 100%, as multiple places where the duplication number should be appended to ensure multiple navigation or master detail properties are handled successfully via code generation. This is exhibited in the support request above, and I am also seeing the same thing with master detail pages. Also the duplication number is not intuitive or developer friendly as you need to remember what #2 is....
So if you are going to have to fix this long term, why not make it more intuitive and extensible at the same time?
The foreign property name solution simplifies the developer experience, and can be implemented in as many unique configurations as needed. As the foreign property name would be unique for each property added...
What I ended up doing was as follows:
Open the following folder in windows explorer: %SOLUTION_PATH%\AspNetZeroRadTool\FileTemplates\Client\Angular\ModuleTemplate
Copy PartialTemplates.txt to PartialTemplates.custom.txt
Find the following two placeholders and add the condition below them.
3.1) "placeholder": "{{Import_Lookup_Table_Here}}", "condition": "'{{NP_Duplication_Number_Here}}' == ''",
3.2) "placeholder": "{{Declare_Lookup_Table_Here}}", "condition": "'{{NP_Duplication_Number_Here}}' == ''",
I found a solution.
The issue was the {{NP_Duplication_Number_Here}} doesn't return '' or 0 as would be expected.
If multiple navigation properties to the same entity are mapped on a new entity, the first one will not return anything if targeting {{NP_Duplication_Number_Here}} in a condition.
All subsequent navigation properties linked to the same entity will return their index (2,3,4,ect...) for {{NP_Duplication_Number_Here}}.
So the trick was to wrap the {{NP_Duplication_Number_Here}} in single quotes like this '{{NP_Duplication_Number_Here}}' this way when it is blank it still returns blank...
My final template condition used for both navigation properties in FileTemplates\Client\Angular\ModuleTemplate\partialtemplates.txt:
Now duplicate import and declarations are no longer being produced via generation.
Is the source for power tools available with paid license?
We have worked with it extensively and have modified the templates to remove the master detail from the main list but on to the details as tabs. Each master details grid is a new tab.
They are only visible after the first save. as otherwise they would have nothing to bind too...
For many applications we feel this is a much better user experience.
We would like to be able to extent the power tools to add some additional properties and control when items are regenerated.
If the source is not available, are there any extensions to add custom properties?
We had a similar situation, on an internal application to manage specific customer transactions, where each customer has it's own tenant.
Our solution was to enable multitenancy, but update the login page to hide the tenant selector. All users logged into host instance via LDAP, with almost no privileges (except for admin level accounts).
We added custom permissions for teach tenant that were assignable to host users to specify what tenant each user has access to.
We set up a dashboard widget that displayed an icon for each tenant filtered by access.
On tenant selection, we check if the current user (by email) is in the target tenant users table. if not we create the user and assign it it the default "users" group in the tenant (additional access is manually configured by tenant administrators). Then we use a new method (slightly modified version of impersonation logic) to impersonate the users tenant user.
We also added a button in the tenant's header that takes (stops impersonation) them back to the tenant selection dashboard widget.
Not sure if this is the best way to handle this, but it is working for us.