Skip to content

Integration

Backend

Initial Configuration

First, reference the DataLoader Client Module in your Application layer:

XML
<ProjectReference Include="$(ServicesPath)DataLoader/ITsynch.Suite.DataLoader.ClientModule/ITsynch.Suite.DataLoader.ClientModule.csproj" />

Define Entities

Before integrating the DataLoader in the respective Application Module, you must define the entities that will represent your data. Create three classes in the Application layer:

Data Entity

Represents the raw structure of the file. Example:

C#
public class SuiteEntityData : IDataEntity
{
    public string FileExtension => DataLoaderConstants.CsvFileExtension;

    public string TemplateProvider => DataLoaderConstants.SuiteTemplateProvider;

    public string Attribute1 { get; set; }

    ...
}

Note

Both FileExtension and TemplateProvider are required by IDataEntity. In this case, the example sets the extension as CSV, but it can be any other file extension. The other properties represent your actual entity data that will come from the file.

Data Loader

Converts the file data into the request type (the type of command/message you want to send). Example:

C#
public class SuiteEntityDataLoader : IDataLoader<SuiteEntityData, CreateOrUpdateEntityByCode>
{
    public async IAsyncEnumerable<CreateOrUpdateEntity> Handle(
        DataLoaderContext<SuiteEntityData> context,
        [EnumeratorCancellation] CancellationToken cancellationToken = default)
    {
        await foreach (var entityData in context.Entities.WithCancellation(cancellationToken))
        {
            var createEntity = new CreateOrUpdateEntity
            {
                Attribute1 = entityData.Attribute1,
                ...
            };

            yield return createEntity;
        }
    }
}

File Mapping

Defines how fields in the source file map to your entity properties. Example:

C#
1
2
3
4
5
6
7
8
9
[TransientDependency(typeof(ClassMap))]
public sealed class SuiteEntityDataMap : ClassMap<SuiteEntityData>
{
    public SuiteEntityDataMap()
    {
        this.Map(m => m.Attribute1).Index(0);
        ...
    }
}

In this example, column index 0 in the file maps to Attribute1.

Add the DataLoader in Application Module

Once your entities and mappings are ready, register the DataLoader in the Application Module. Example:

C#
public override void SetupModule(IModuleBuilder builder)
{
    base.SetupModule(builder);

    builder.DependsOn<DataLoaderClientModule, DataLoaderClientModuleOptions>(options =>
        {
            options.AddDataLoaderFor<Entity, CreateOrUpdateEntity>(cfg =>
                cfg.HasDataType<SuiteEntityData>()
                    .Produces<EntityUpdated>()
                    .HandledBy<SuiteEntityDataLoader>()
                    .WithIdentifier(x => x.Attribute1)
                    .WithBatchSize(20));
        });
}

This dependency can be explained in different parts:

  • AddDataLoaderFor<Entity, CreateOrUpdateEntity>(cfg => …): Creates and configures a new DataLoaderDescriptor for the entity type (Entity) and the request type (CreateOrUpdateEntity).
  • HasDataType<SuiteEntityData>(): Registers the class that represents the incoming file data.
  • Produces<EntityUpdated>(): Defines the awaited response message produced when the data is processed.
  • HandledBy<SuiteEntityDataLoader>(): Assigns the transformer class that maps the file data to the request type.
  • WithIdentifier(): Defines the property used to uniquely identify records.
  • WithBatchSize(int): Sets how many rows are processed per batch. By default the value is 20.

Configure Federation

Finally, expose the DataLoader service through your GraphQL federation setup:

C#
1
2
3
4
5
internal static void ConfigureFederations(this GraphQLGatewayModuleOptions options)
    {
        ...
        options.RemoteSchemas.Add("data_loader", "data-loader-service");
    }

This makes the DataLoader service accessible through the gateway, completing the backend integration.

Frontend

To enable the DataLoader feature in the UI you have to define a DataLoader action by using createDataLoaderAction. Example:

TypeScript
1
2
3
export const dataLoaderClicked = createDataLoaderAction(
    '[Entity List] Data loader clicked'
);

Then, bind said action to the entity list by using enableDataLoader. Example:

TypeScript
1
2
3
4
5
.enableDataLoader(
    dataLoaderClicked({
        wellKnownName: ENTITY_WELL_KNOWN_NAME
    })
)