Browse Source

Docs: update Fluent API examples and add image

Update low-code Fluent API docs: add docs/en/images/quick-look.png and refactor examples to use DynamicEntityBase for entities. Remove the separate assembly registration step and replace the ConfigureServices sample with a Low-Code initializer (MyAppLowCodeInitializer) that uses AsyncOneTimeRunner and an async InitializeAsync which calls DynamicModelManager.Instance.InitializeAsync(). Also adjust step numbering and small samples to reflect these API changes (add server-only/internal property, set UI descriptors, etc.).
pull/25021/head
SALİH ÖZKARA 1 month ago
parent
commit
2e945ee802
  1. BIN
      docs/en/images/quick-look.png
  2. 83
      docs/en/low-code/fluent-api.md

BIN
docs/en/images/quick-look.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

83
docs/en/low-code/fluent-api.md

@ -16,7 +16,7 @@ C# Attributes and the Fluent API are the **recommended way** to define dynamic e
````csharp ````csharp
[DynamicEntity] [DynamicEntity]
[DynamicEntityUI(PageTitle = "Products")] [DynamicEntityUI(PageTitle = "Products")]
public class Product public class Product : DynamicEntityBase
{ {
[DynamicPropertyUnique] [DynamicPropertyUnique]
public string Name { get; set; } public string Name { get; set; }
@ -30,18 +30,7 @@ public class Product
} }
```` ````
### Step 2: Register the Assembly ### Step 2: Add Migration and Run
````csharp
public override void ConfigureServices(ServiceConfigurationContext context)
{
AbpDynamicEntityConfig.SourceAssemblies.Add(
new DynamicEntityAssemblyInfo(typeof(YourDomainModule).Assembly)
);
}
````
### Step 3: Add Migration and Run
```bash ```bash
dotnet ef migrations add Added_Product dotnet ef migrations add Added_Product
@ -50,12 +39,12 @@ dotnet ef database update
You now have a complete Product management page with data grid, create/edit modals, search, sorting, and pagination. You now have a complete Product management page with data grid, create/edit modals, search, sorting, and pagination.
### Step 4: Add Relationships ### Step 3: Add Relationships
````csharp ````csharp
[DynamicEntity] [DynamicEntity]
[DynamicEntityUI(PageTitle = "Orders")] [DynamicEntityUI(PageTitle = "Orders")]
public class Order public class Order : DynamicEntityBase
{ {
[DynamicForeignKey("MyApp.Customers.Customer", "Name", ForeignAccess.Edit)] [DynamicForeignKey("MyApp.Customers.Customer", "Name", ForeignAccess.Edit)]
public Guid CustomerId { get; set; } public Guid CustomerId { get; set; }
@ -65,7 +54,7 @@ public class Order
} }
[DynamicEntity(Parent = "MyApp.Orders.Order")] [DynamicEntity(Parent = "MyApp.Orders.Order")]
public class OrderLine public class OrderLine : DynamicEntityBase
{ {
[DynamicForeignKey("MyApp.Products.Product", "Name")] [DynamicForeignKey("MyApp.Products.Product", "Name")]
public Guid ProductId { get; set; } public Guid ProductId { get; set; }
@ -97,7 +86,7 @@ Marks a class as a dynamic entity. The entity name is derived from the class nam
````csharp ````csharp
[DynamicEntity] [DynamicEntity]
public class Product public class Product : DynamicEntityBase
{ {
public string Name { get; set; } public string Name { get; set; }
public decimal Price { get; set; } public decimal Price { get; set; }
@ -108,7 +97,7 @@ Use the `Parent` property for parent-child (master-detail) relationships:
````csharp ````csharp
[DynamicEntity(Parent = "MyApp.Orders.Order")] [DynamicEntity(Parent = "MyApp.Orders.Order")]
public class OrderLine public class OrderLine : DynamicEntityBase
{ {
public Guid ProductId { get; set; } public Guid ProductId { get; set; }
public int Quantity { get; set; } public int Quantity { get; set; }
@ -122,7 +111,7 @@ Configures entity-level UI. Entities with `PageTitle` get a menu item and a dedi
````csharp ````csharp
[DynamicEntity] [DynamicEntity]
[DynamicEntityUI(PageTitle = "Product Management")] [DynamicEntityUI(PageTitle = "Product Management")]
public class Product public class Product : DynamicEntityBase
{ {
// ... // ...
} }
@ -215,7 +204,7 @@ Defines JavaScript interceptors on a class for CRUD lifecycle hooks:
InterceptorType.Post, InterceptorType.Post,
"context.log('Deleted: ' + context.commandArgs.entityId);" "context.log('Deleted: ' + context.commandArgs.entityId);"
)] )]
public class Organization public class Organization : DynamicEntityBase
{ {
public string Name { get; set; } public string Name { get; set; }
} }
@ -245,7 +234,7 @@ Reference in an entity:
````csharp ````csharp
[DynamicEntity] [DynamicEntity]
[DynamicEntityUI(PageTitle = "Organizations")] [DynamicEntityUI(PageTitle = "Organizations")]
public class Organization public class Organization : DynamicEntityBase
{ {
public string Name { get; set; } public string Name { get; set; }
public OrganizationType OrganizationType { get; set; } public OrganizationType OrganizationType { get; set; }
@ -276,28 +265,38 @@ The Fluent API has the **highest priority** in the configuration system. Use `Ab
### Basic Usage ### Basic Usage
Configure in your Domain module's `ConfigureServices`: Configure in your Low-Code Initializer (e.g. `MyAppLowCodeInitializer`):
````csharp ````csharp
public override void ConfigureServices(ServiceConfigurationContext context) public static class MyAppLowCodeInitializer
{ {
AbpDynamicEntityConfig.EntityConfigurations.Configure( private static readonly AsyncOneTimeRunner Runner = new();
"MyApp.Products.Product",
entity =>
{
entity.DefaultDisplayPropertyName = "Name";
var priceProperty = entity.AddOrGetProperty("Price"); public static async Task InitializeAsync()
priceProperty.AsRequired(); {
priceProperty.UI = new EntityPropertyUIDescriptor await Runner.RunAsync(async () =>
{ {
DisplayName = "Unit Price", AbpDynamicEntityConfig.EntityConfigurations.Configure(
CreationFormAvailability = EntityPropertyUIFormAvailability.Available "MyApp.Products.Product",
}; entity =>
{
entity.DefaultDisplayPropertyName = "Name";
var priceProperty = entity.AddOrGetProperty("Price");
priceProperty.AsRequired();
priceProperty.UI = new EntityPropertyUIDescriptor
{
DisplayName = "Unit Price",
CreationFormAvailability = EntityPropertyUIFormAvailability.Available
};
entity.AddOrGetProperty("InternalNotes").AsServerOnly();
}
);
entity.AddOrGetProperty("InternalNotes").AsServerOnly(); await DynamicModelManager.Instance.InitializeAsync();
} });
); }
} }
```` ````
@ -439,7 +438,7 @@ public enum OrderStatus
// Customer entity // Customer entity
[DynamicEntity] [DynamicEntity]
[DynamicEntityUI(PageTitle = "Customers")] [DynamicEntityUI(PageTitle = "Customers")]
public class Customer public class Customer : DynamicEntityBase
{ {
[DynamicPropertyUnique] [DynamicPropertyUnique]
public string Name { get; set; } public string Name { get; set; }
@ -457,7 +456,7 @@ public class Customer
// Product entity // Product entity
[DynamicEntity] [DynamicEntity]
[DynamicEntityUI(PageTitle = "Products")] [DynamicEntityUI(PageTitle = "Products")]
public class Product public class Product : DynamicEntityBase
{ {
[DynamicPropertyUnique] [DynamicPropertyUnique]
public string Name { get; set; } public string Name { get; set; }
@ -478,7 +477,7 @@ public class Product
} }
}" }"
)] )]
public class Order public class Order : DynamicEntityBase
{ {
[DynamicForeignKey("MyApp.Customers.Customer", "Name", ForeignAccess.Edit)] [DynamicForeignKey("MyApp.Customers.Customer", "Name", ForeignAccess.Edit)]
public Guid CustomerId { get; set; } public Guid CustomerId { get; set; }
@ -489,7 +488,7 @@ public class Order
} }
[DynamicEntity(Parent = "MyApp.Orders.Order")] [DynamicEntity(Parent = "MyApp.Orders.Order")]
public class OrderLine public class OrderLine : DynamicEntityBase
{ {
[DynamicForeignKey("MyApp.Products.Product", "Name")] [DynamicForeignKey("MyApp.Products.Product", "Name")]
public Guid ProductId { get; set; } public Guid ProductId { get; set; }

Loading…
Cancel
Save