Closed leonAtRain closed 1 year ago
Hi @leonAtRain. To answer your question, there are a few ways you can go about achieving that.
It is best practice to rather check for the existence of a Template Instance that gets installed by your gRpc module than it is to check directly whether the gRpc module is installed. This is to cater for scenarios where you may perform refactoring later and to decouple your modules by not referencing them directly. You can do this check inside your Template
or Software Factory Extension
that needs to detect whether gRpc is installed.
If you are in the context of a Template
, you can use the TryGetTemplate
method which will perform a search and return a template instance based on a Template Id
or Role
name.
The Template Id / Role name can target the Template that is present inside your gRpc module and if the method returns an instance, then you know the module is present and you can do certain logic then.
If the code in question lies inside a Software Factory Extension
, you can leverage the IApplication
object to make use of the FindTemplateIntance
method which works similar to the TryGetTemplate
method.
Otherwise if your module does not have a template but you wish to check that it is installed, the IApplication
(for Software Factory Extensions) and ExecutionContext
(for Templates) also has a InstalledModules
property that holds a list of all the Modules (their Module Ids) that's installed. You can perform a .Any(x => x.ModuleId == "MyModuleId")
check on them to see if your module is present.
I hope that those options will help you.
I Thought I got it , but I'm doing something wrong: ITemplate templat; if (TryGetTemplate("Rain.Module.Grpc.ServiceImpl", out templat)) { members.Add(string.Join(Environment.NewLine, CreateToDtoGrpcMethod())); }
my SF is showing me this nice message:
System.Exception: Error occurred in Template: RainModelMapping.DtoEntityMapper [[DTO: AccountBalanceDto - ec54faf1-c687-45cb-b738-92ed915654a0]]
---> System.Exception: More than one instance of template Rain.Module.Grpc.ServiceImpl was found. Rain.Module.Grpc.ServiceImpl [[Service: BillFormatService - 02866016-2942-4bf5-8782-e2ca9801278a]], Rain.Module.Grpc.ServiceImpl [[Service: BillingAccountService - bc0a690f-0563-487b-9f0f-76a5c6168bfa]], Rain.Module.Grpc.ServiceImpl [[Service: BillingCycleSpecificationService - e53a99dc-75d0-41bc-b522-ff6eb399cf0d]], Rain.Module.Grpc.ServiceImpl [[Service: FinancialAccountService - 663fb459-1ea5-43d1-81fc-7d4ae974a72c]], Rain.Module.Grpc.ServiceImpl [[Service: PartyAccountService - 55802915-de8f-4bdf-93ca-124f63a796bf]], Rain.Module.Grpc.ServiceImpl [[Service: SettlementAccountService - 44965307-06a5-433b-9fc7-d8eb12d560e3]]
at Intent.SoftwareFactory.Engine.Runtime.ApplicationManager.FindTemplateInstance(String templateIdOrRole, Func2 predicate) in D:\AzureDevOpsAgents\IntentProprietaryRepository\_work\1\s\Intent.IntentArchitect\IntentArchitect.SoftwareFactory\Intent.SoftwareFactory\Engine\Runtime\ApplicationManager.cs:line 505 at Intent.Modules.Common.SoftwareFactoryExecutionContextExtensions.FindTemplateInstance[TTemplate](ISoftwareFactoryExecutionContext executionContext, String templateId) in /home/vsts/work/1/s/Modules/Intent.Modules.Common/Engine/SoftwareFactoryExecutionContextExtensions.cs:line 66 at Intent.Modules.Common.Templates.IntentTemplateBase.<>c__DisplayClass82_0
1.1 getTemplate, Func
1 getDependencyDescriptionForException, TemplateDiscoveryOptions options) in /home/vsts/work/1/s/Modules/Intent.Modules.Common/Templates/IntentTemplateBase.cs:line 1166
at Intent.Modules.Common.Templates.IntentTemplateBase.GetTemplate[TTemplate](String templateId, TemplateDiscoveryOptions options) in /home/vsts/work/1/s/Modules/Intent.Modules.Common/Templates/IntentTemplateBase.cs:line 1231
at Intent.Modules.Common.Templates.IntentTemplateBase.TryGetTemplate[TTemplate](String templateId, TTemplate& template) in /home/vsts/work/1/s/Modules/Intent.Modules.Common/Templates/IntentTemplateBase.cs:line 1243
at RainModelMapping.Templates.DtoEntityMapper.DtoEntityMapperTemplate.GetMembers() in C:\Users\LeonNortjie\source\repos\Rain.IntentModules\RainModelMapping\Templates\DtoEntityMapper\DtoEntityMapperTemplate.cs:line 76
at RainModelMapping.Templates.DtoEntityMapper.DtoEntityMapperTemplate.TransformText() in C:\Users\LeonNortjie\source\repos\Rain.IntentModules\RainModelMapping\Templates\DtoEntityMapper\DtoEntityMapperTemplate.cs:line 43
at Intent.Modules.Common.Templates.IntentTemplateBase.RunTemplate() in /home/vsts/work/1/s/Modules/Intent.Modules.Common/Templates/IntentTemplateBase.cs:line 189
at Intent.Modules.Common.Java.Templates.JavaTemplateBase1.GetTemplateFile() in /home/vsts/work/1/s/Modules/Intent.Modules.Common.Java/Templates/JavaTemplateBase.cs:line 169 at Intent.Modules.Common.Java.Templates.JavaTemplateBase
1.RunTemplate() in /home/vsts/work/1/s/Modules/Intent.Modules.Common.Java/Templates/JavaTemplateBase.cs:line 215
at Intent.SoftwareFactory.Templates.TemplateOutput.GenerateOutput() in D:\AzureDevOpsAgents\IntentProprietaryRepository_work\1\s\Intent.IntentArchitect\IntentArchitect.SoftwareFactory\Intent.SoftwareFactory\Templates\Outputs\TemplateOutput.cs:line 31
--- End of inner exception stack trace ---
at Intent.SoftwareFactory.Templates.TemplateOutput.GenerateOutput() in D:\AzureDevOpsAgents\IntentProprietaryRepository_work\1\s\Intent.IntentArchitect\IntentArchitect.SoftwareFactory\Intent.SoftwareFactory\Templates\Outputs\TemplateOutput.cs:line 35
at Intent.SoftwareFactory.Engine.OutputFile..ctor(IOutputTarget project, ITemplateOutput templateOutput, IFileLog existingFileInfo, ISoftwareFactoryEventDispatcher eventDispatcher) in D:\AzureDevOpsAgents\IntentProprietaryRepository_work\1\s\Intent.IntentArchitect\IntentArchitect.SoftwareFactory\Intent.SoftwareFactory\Engine\Output\OutputFile.cs:line 30
at Intent.SoftwareFactory.ProcessOrchestration.<>cDisplayClass18_2.
I've found something that works -
if (ExecutionContext.GetApplicationTemplates().Any(t => t.Id.Equals("Rain.Module.Grpc.ServiceImpl")))
{
members.Add(string.Join(Environment.NewLine, CreateToDtoGrpcMethod()));
}
Would this still qualify as Best practice?
Hi @leonAtRain.
The error you are experiencing has to do with the fact that there is more than one template instance that was found so the TryGetTemplate
method will not suffice in that case since it assumes there will be only a single Template Instance to be returned however, there is an overload where you can pass in a specific model to find a specific Template Instance if you have it available.
Assuming you don't have the model at hand, you can do the following:
var serviceTemplates = this.ExecutionContext.FindTemplateInstances<IClassProvider>(TemplateDependency.OnTemplate("Rain.Module.Grpc.ServiceImpl"));
if (serviceTemplates.Any())
{
members.Add(string.Join(Environment.NewLine, CreateToDtoGrpcMethod()));
}
I hope this will clear up your concern. However, I do think it is worth mentioning that in the case where you would like to add code based on the existence of another Module, you may want to look at the Java File Builder Pattern. I am happy to take you through it if you are keen.
Hi @leonAtRain, we're closing this ticket, but let us know if there is anything unclear here.
Ask a question
We've got our own implementation of the Mapstruct as a module that is customized for our scenario. I've implemented a gRpc module which also requires a specific map to be added to the Mapstruct interface. My question is - while generating the mapper template, is it possible to know if the gRPC module is active in the specific application that I can make the necessary changes - if the module is not there, it would just skip that step.