@albert You can do generation in any type of files. Only in c# classes you can have region merge (comming from the model) into your customized code. I use some of these files: https://github.com/loresoft/EntityFrameworkCore.Generator/tree/master/src/EntityFrameworkCore.Generator.Core/Parsing
If you see the project references I am using: <PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.1.0" /> <PackageReference Include="Microsoft.CodeAnalysis.CSharp.Scripting" Version="4.1.0" /> for merge strategy. You can see how do my entities look like (with REG_REGION prefixed c# regions - making them ready for code re-generation) You can see 3 entities from the domain project being generated and re-generated (when there is a change to model) https://github.com/radrad/Acme.HelpDesk/blob/master/Acme.Bookstore.Domain.zip Your custom code can go anywhere outside REG_REGIONs and it will be preserved
I chose to have the merge strategy within once file instead of having a partial class and making custom changes in another related partial class becuase I wanted to see the whole file and properties.
These are model definiton in Telosys DSL language: `Deal.entity: Deal { Id : string { @Id #ignore }; DealName : string { @NotNull @NotBlank @SizeMin(20) @SizeMax(30) }; Zip : string { @Pattern("\d{5}") }; GameId : string { #optional @FK(FK_GAME, Game.Id) }; Game : Game; Players : Player[]; Author : Author { @NotNull }; }
Game.entity: Game { Id : string { @Id #ignore }; GameName : string { @NotNull @NotBlank @SizeMin(5) @SizeMax(20) }; Rating : int { @Min(1) @Max(5) }; StartDate : date { @Optional }; Email : string { @NotNull @NotBlank #ValidationEmail }; }
Player.entity: Player { Id : string { @Id #ignore }; FirstName : string { @SizeMax(20) }; LastName : string { @SizeMax(20) }; BirthDate : date { @Past } ; Certified : boolean ; }`
There could be some custom "preserve" region for other kind of file types where you can use smart commenting to discover/register re-generatable regions. I did't work on it, but you can always use some smart c# parsing (maybe regex: https://csharp.net-tutorials.com/it/419/regular-expressions-regex/search-replace-with-the-regex-class/) to replace these regions with new incomming regions. (C# class is given pre-generation output that you can manipulate in any ways possible). There could be some libraries that can do the job for you.
Server side Comments:
Razor Pages .cshtml @* Gen Start (Don't change, it will be re-generated) @ ... will be re-generated <input name="firstName">... loop over all properties in your dsl model and output <input name="City">... loop over all properties in your dsl model and output @ Gen End *@
Web form .aspx <%-- Gen Start (Don't change, it will be re-generated) --%> ... will be re-generated <%-- Gen End --%>
Client Side Comments
HTML Comments <!-- Gen Start (Don't change, it will be re-generated) --> ... will be re-generated <!-- Gen End -->
Javascript Comment //Gen Start (Don't change, it will be re-generated) ... will be re-generated //Gen End
/* Gen Start (Don't change, it will be re-generated) / ... will be re-generated / Gen End */
CSS comments: /* This is a single-line comment */ But I would not envision any CSS styling based on the model
You can do the same techniquest for any c# code that can have #region .... #end region segments. If you are sure that whatever goes into these "code generation" regions depends on your DSL model fields you can do it for c# only code.
@albert. It is easier than you think. I am using this strategy https://efg.loresoft.com/en/latest/regeneration/ I manage to extend telosys velocity code and connect my custom C# method using Java to .Net bridge and my c# code uses native c # classes to parse c# regions and simply only affect #region …. #end region area into which I only generate things from the model taking any new changes and rendering them in those regions. All other code is under your control to customize and it won’t be touched by this method
I have started to build a abp code generation tool around telsoys cli and velocity engine. We can collaborate on it. I have one template/page ready: Domain entity. It is based on DSL language that telosys offers. You can use vs code telosys extension to write your entities or Eclipse plugin. It allows both generation from a model class or from DB table. You can see videos: https://www.youtube.com/channel/UCX5-ypQygEHMCGXVTTbhfNQ I basically build a tooling to enable telosys tool to be abp aware. My generation allows code re-generation, so you can preserve your custom code. Let me know if you are interested.
Rad
This will not enable EF migration to take control of future changes. This will enable you use EF with abp.io.
Thanks @mailming,
To conclude. If a project (module A) doesn't have embeded resources: js, css, json, razor files or entything with that is marked as embeded resource and if the module is referenced by another module B or host project P we don't need to add ReplaceEmbeddedByPhysical and point to that module A in either module B or host project P.
If this is correct there are many places in ABP framework, modules, samples where we don't have consistent ReplaceEmbeddedByPhysical pointers to only those modules that actually have embeded resources. Maybe we have them to enable referenced modules to be able to host some embeded resources and we do it just in case.
Can you please clarify so I can confidently use ReplaceEmbeddedByPhysical when I am dealing with runtime changes of underlying resources that should be reflected in the GUI.
Thanks
Hi again,
do you have any source code examples on GitHub? Any template? At the moment the existing database has more than 300 tables and applying this workaround to each table and testing it will take an eon. And it is not only the change of the primary key. The saas adds its own columns that in your scenario should be added manually. If you have a complete whitepaper of porting to ABP framework an existing database schema it will be more than welcome.
Best regards,
Stavros Raptis
This is involved. @mailming mentioned you could buy abp commercial version. There is a way to do it without it and to find a way for migration to continue to handle further develpment. You can contact me at radvistaATgmailDOTnet
@mailming When I will know if I am using virtual files? Is this necessary when adding a theme project to your solution and when you want to reference that theme and use it in your module (host app)? If yes, what is using virtual files: host app module or theme module? Can you please clarify as I asked similar question above. I mentioned development time too. Can you comment.
Thanks
Assuming you have this existing table: CREATE TABLE AbpOrganizations ( OrganizationID int IDENTITY(1,1) PRIMARY KEY, Name varchar(255) NOT NULL );
You need to understand these settings: // Configures a property to never have a value generated when an instance of this // entity type is saved. // Note that temporary values may still be generated for use internally before a // new entity is saved. public new virtual PropertyBuilder<TProperty> ValueGeneratedNever()
// Configures a property to have a value generated only when saving a new entity, // unless a non-null, non-temporary value has been set, in which case the set value // will be saved instead. The value may be generated by a client-side value generator // or may be generated by the database as part of saving the entity. public new virtual PropertyBuilder<TProperty> ValueGeneratedOnAdd()
builder.Entity<Organization>(b => { b.ToTable(EventHubConsts.DbTablePrefix + "Organizations", EventHubConsts.DbSchema); b.ConfigureByConvention(); b.Property(x => x.Id).HasColumnName("OrganizationID").ValueGeneratedNever();
public class Organization : Entity<int> { public string Name { get; private set; } }
You need to make your model always in sync with DB. I think you cannot do code migrations, unless extra work is done to synchronize model with DB.
I am not sure if redis will really improve the performance that much (depending on what is being cached and how much data your are storing in redis). This is how it is being configured and added.
https://github.com/abpframework/eShopOnAbp/blob/main/services/basket/src/EShopOnAbp.BasketService/appsettings.json "Redis": { "Configuration": "localhost:6379" },
https://github.com/abpframework/eShopOnAbp/blob/main/shared/EShopOnAbp.Shared.Hosting.Microservices/EShopOnAbpSharedHostingMicroservicesModule.cs
var redis = ConnectionMultiplexer.Connect(configuration["Redis:Configuration"]);
context.Services
.AddDataProtection()
.PersistKeysToStackExchangeRedis(redis, "EShopOnAbp-Protection-Keys");