OfX 3.1.13
See the version list below for details.
dotnet add package OfX --version 3.1.13
NuGet\Install-Package OfX -Version 3.1.13
<PackageReference Include="OfX" Version="3.1.13" />
paket add OfX --version 3.1.13
#r "nuget: OfX, 3.1.13"
// Install OfX as a Cake Addin #addin nuget:?package=OfX&version=3.1.13 // Install OfX as a Cake Tool #tool nuget:?package=OfX&version=3.1.13
OfX
OfX is an open-source, which focus on Attribute-based data mapping, streamlines data handling across services, reduces boilerplate code, and improves maintainability
Project Highlights
Attribute-based Data Mapping in OfX is a feature that lets developers annotate properties in their data models with custom attributes. These attributes define how and from where data should be fetched, eliminating repetitive code and automating data retrieval.
For example, imagine a scenario where Service A needs a user’s name stored in Service B. With Attribute-based Data Mapping, Service A can define a UserName property annotated with [UserOf(nameof(UserId))]
. This tells the system to automatically retrieve the UserName based on UserId, without writing custom code each time.
Example:
public sealed class SomeDataResponse
{
public string Id { get; set; }
public string UserId { get; set; }
[UserOf(nameof(UserId), Expression = "Email")]
public string UserEmail { get; set; }
[UserOf(nameof(UserId))] public string UserName { get; set; }
...
}
The [UserOf]
annotation acts as a directive to automatically retrieve UserName
based on UserId
,you can also fetch custom fields as Email
on the User Table using Expression like [UserOf(nameof(UserId), Expression="Email")]
. This eliminates the need for manual mapping logic, freeing developers to focus on core functionality rather than data plumbing.
Start with OfX
To install the OfX package, use the following NuGet command:
dotnet add package OfX
Or via the NuGet Package Manager:
Install-Package OfX
How to Use
1. Register OfX in the Dependency Injection Container
Add the OfX to your service configuration to register OfX:
builder.Services.AddOfX(cfg =>
{
cfg.AddAttributesContainNamespaces(typeof(WhereTheAttributeDefined).Assembly);
cfg.AddHandlersFromNamespaceContaining<SomeHandlerAssemblyMarker>(); //<- Add this one when you want to self-handle the request as the example at the end of this guide. Otherwise, if you install the package OfX-gRPC or OfX-Nats...(like OfX transport extension package), there is no need to add this one anymore!
cfg.AddReceivedPipelines(c => c.OfType(typeof(GenericReceivedPipeline<>).OfType<OtherReceivedPipeline>());
cfg.AddSendPipelines(c => c.OfType(typeof(GenericSendPipeline<>).OfType(typeof(OtherSendPipeline<>)));
// When you have the stronglyTypeId, you have to create the config how to resolve the Id(from string type) to StronglyTypeId
cfg.AddStronglyTypeIdConverter(a => a.OfType<StronglyTypeIdRegisters>());
});
StronglyTypeIdRegister Example:
// StronglyTypeIdRegisters example:
public sealed class StronglyTypeIdRegisters : IStronglyTypeConverter<UserId>
{
public UserId Convert(string input) => new UserId(input);
public bool CanConvert(string input) => true;
}
// You can also implement many IStronglyTypeConverter<T>
Function Descriptions
AddAttributesContainNamespaces
Registers assemblies that contain the attributes, used by OfX for data mapping.
The Attribute must be inherited from OfXAttribute
and they will be scanned by OfX!
Parameters:
Assembly
: The assembly containing the (OfX) attributes.
AddHandlersFromNamespaceContaining
Add assemblies that contain handlers responsible for processing queries or commands for data retrieval.
Handlers are the execution units that resolve attributes applied to models.
If this function is not invoked. The default value ItemsResponse<OfXDataResponse>
is returned!
Parameters:
Type
: A marker type within the assembly that includes the handler implementations.
Example:
cfg.AddHandlersFromNamespaceContaining<SomeHandlerAssemblyMarker>();
Here, AddHandlersFromNamespaceContaining
is a type within the assembly where your handler logic resides.
AddReceivedPipelines
When you want to create pipelines to handle the received request for OfXAttribute
. You should use it on the server, where you fetching and response to client!
Parameters:
Action<ReceivedPipeline>
: add the pipelines.
Example:
cfg.AddSendPipelines(c => c.OfType(typeof(GenericSendPipeline<>).OfType(typeof(OtherSendPipeline<>)));
AddSendPipelines
When you want to create pipelines to handle the send request for OfXAttribute
. You should use it on the client, where you send request to get data!
Parameters:
Action<SendPipeline>
: add the pipelines.
Example:
cfg.AddReceivedPipelines(c => c.OfType(typeof(GenericPipeline<>)).OfType<OtherPipeline>());
AddStronglyTypeIdConverter
When your models(entities) are using Strongly Type Id, you have to configure to tell how OfX can convert from general ID type(string) to your strongly type ID.
Parameters:
Action<StronglyTypeIdRegister>
the strongly type ID register delegate.
OfType
You have to create a class and implement interface IStronglyTypeConverter<T>
, then you have to override 2 methods(Convert
and CanConvert
) to help OfX convert from general Id type(string) to your strongly type.
Please check the example above!
2. Integrate the OfXAttribute
into Your Models, Entities, or DTOs
Apply the attribute to your properties like this:
public sealed class SomeDataResponse
{
public string Id { get; set; }
public string UserId { get; set; }
[UserOf(nameof(UserId), Expression = "Email")]
public string UserEmail { get; set; }
[UserOf(nameof(UserId))]
public string UserName { get; set; }
[UserOf(nameof(UserId), Expression = "ProvinceId")]
public string ProvinceId { get; set; }
[ProvinceOf(nameof(ProvinceId), Order = 1)]
public string ProvinceName { get; set; }
[ProvinceOf(nameof(ProvinceId), Expression = "Country.Name", Order = 1)]
public string CountryName { get; set; }
// Add other properties as needed
}
3. Annotate OfXConfigForAttribute
your models with OfXAttribute
to then OfX
will dynamic create relevant proxy handler for model and OfXAttribute
Example:
[OfXConfigFor<UserOfAttribute>(nameof(Id), nameof(Name))]
public class User
{
public string Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public string ProvinceId {get; set;}
}
4. Write the Handlers in Your Service to Fetch the Data(when you are using OfX
only).
Note:
If you use OfX-gRPC, OfX-Nats, OfX-RabbitMq... or other transport data layer(next version extension packages), there are no need to create Handlers anymore, they should be dynamic proxy handlers!
Implement a handler to process data requests.
Example:
public class UserRequestHandler(): IMappableRequestHandler<UserOfAttribute>
{
public async Task<ItemsResponse<OfXDataResponse>> RequestAsync(RequestContext<UserOfAttribute> request)
{
// Implement data fetching logic here (e.g., via REST, RPC, or gRPC)
}
}
That all, Enjoy your moment!
| Package Name | Description | .NET Version | Document | |--------------------------------------------------------------|---------------------------------------------------------------------------------------------------------|--------------|------------------------------------------------------------------------------------------| | OfX | OfX core | 8.0, 9.0 | This Document | | OfX-EFCore | This is the OfX extension package using EntityFramework to fetch data | 8.0, 9.0 | ReadMe | | OfX-gRPC | OfX.gRPC is an extension package for OfX that leverages gRPC for efficient data transportation. | 8.0, 9.0 | ReadMe | | OfX-Nats | OfX-Nats is an extension package for OfX that leverages Nats for efficient data transportation. | 8.0, 9.0 | ReadMe | | OfX-RabbitMq | OfX-RabbitMq is an extension package for OfX that leverages RabbitMq for efficient data transportation. | 8.0, 9.0 | ReadMe | | OfX-Kafka | OfX-Kafka is an extension package for OfX that leverages Kafka for efficient data transportation. | 8.0, 9.0 | ReadMe |
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. |
-
net8.0
-
net9.0
NuGet packages (6)
Showing the top 5 NuGet packages that depend on OfX:
Package | Downloads |
---|---|
OfX-EFCore
OfX extension. Use EntityFramework as Data Querying |
|
OfX-gRPC
OfX extension. Use gRPC as Data transporting |
|
OfX-Nats
Nats.io extension. Use Nats as Data transporting |
|
OfX-RabbitMq
OfX-RabbitMq extension. Use RabbitMq as Data transporting |
|
OfX-Kafka
OfX-Kafka extension. Use Kafka as Data transporting |
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated |
---|---|---|
4.0.0 | 26 | 2/4/2025 |
3.3.3 | 56 | 2/4/2025 |
3.3.2 | 79 | 2/3/2025 |
3.3.1 | 75 | 2/1/2025 |
3.3.0 | 89 | 1/22/2025 |
3.2.1 | 103 | 1/22/2025 |
3.2.0 | 97 | 1/21/2025 |
3.1.13 | 96 | 1/18/2025 |
3.1.12 | 104 | 1/16/2025 |
3.1.11 | 87 | 1/13/2025 |
3.1.10 | 90 | 1/12/2025 |
3.1.9 | 88 | 1/10/2025 |
3.1.8 | 73 | 1/8/2025 |
3.1.7 | 95 | 1/7/2025 |
3.1.6 | 100 | 1/6/2025 |
3.1.5 | 100 | 1/5/2025 |
3.1.4 | 113 | 1/4/2025 |
3.1.3 | 115 | 1/4/2025 |
3.1.2 | 117 | 1/4/2025 |
3.1.1 | 118 | 1/3/2025 |
3.1.0 | 98 | 12/31/2024 |
3.0.5 | 86 | 12/30/2024 |
3.0.4 | 83 | 12/30/2024 |
3.0.3 | 91 | 12/30/2024 |
3.0.2 | 94 | 12/30/2024 |
3.0.1 | 88 | 12/30/2024 |
3.0.0 | 97 | 12/30/2024 |
2.0.3 | 100 | 12/30/2024 |
2.0.2 | 94 | 12/29/2024 |
2.0.1 | 94 | 12/29/2024 |
2.0.0 | 92 | 12/28/2024 |
1.1.4 | 103 | 12/27/2024 |
1.1.3 | 97 | 12/26/2024 |
1.1.2 | 101 | 12/26/2024 |
1.1.1 | 100 | 12/26/2024 |
1.1.0 | 92 | 12/25/2024 |
1.0.8 | 102 | 12/25/2024 |
1.0.7 | 93 | 12/25/2024 |
1.0.6 | 115 | 12/25/2024 |
1.0.5 | 80 | 12/24/2024 |
1.0.4 | 92 | 12/24/2024 |
1.0.3 | 81 | 12/24/2024 |
1.0.2 | 80 | 12/24/2024 |
1.0.1 | 82 | 12/24/2024 |
1.0.0 | 78 | 12/23/2024 |