-
Notifications
You must be signed in to change notification settings - Fork 21
User_Defined_Attributes
A new powerful option in v6.0.0+ to dynamically generate attributes for c# classes and properties using a simple text file
A new powerful option --att-defs allows you to dynamically generate attributes for c# classes and properties using a simple text file that contains your template with expressions. These expressions are valid C# code that can utilize C# string functions and other built-in extension methods. You can also filter on classes and properties to apply the attributes selectively.
To use the feature:
- Add the following option to the commandLine:
--att-defs path/to/file
- Create a text file (ini format) with the minimal code as given below:
# the attribute for all properties only (exclude classes).
[myJson]
Format=[JsonProperty ("{{PropName.ToCamelCase()}}")]
# the attribute for all classes only (exclude properties)
[map]
Scope= class
Format= [AdaptTo("[name]Dto")]
The above file, define an attribute named 'myJson' with the Format entry which will be applied to all properties of the class.
The expression is evaluated for every property / class. The Format is the syntax of the attribute with the expressions enclosed between {{...}}. The expression {{PropName.ToCamelCase().Quote()}}
is evaluated with the actual value of PropName
with applying the built-in extension methods in OData2Poco 'ToCamelCase()'.
The name of the attribute is the section name, e.g [myJson]
The result is like:
[AdaptTo("[name]Dto")]
public partial class Manager : Person
{
[JsonProperty ("budget")]
public long Budget {get;set;} // not null
[JsonProperty ("bossOffice")]
public Location BossOffice {get;set;}
}
As you see, the 'budget' is the camelCase of the name of the property 'Budget'
The file is ini-format and it's composed of following entries:
-
Name of attribute (section name) which is enclosed between brackets [...]
-
The Scope with a lowercase value: 'property' or 'class'. The default value is 'property' and can be be dropped.
- For property scope, attribute is applied for Properties only.
- For class scope, attribute is applied for classes only.
-
The Format (mandatory entry): is the syntax of the attribute with expressions enclosed between {{...}}.
-
The Filter (an optional entry). It is a valid c# expression of one c# expression code. The expression can reference any property in the class
PropertyTemplate
orClassTemplate
-
The line start with # is a comment and it's ognored by the parser.
-
Attributes without Format will be ignored, but the cli tool display a warning message.
-
The expression is valid C# code that can utilize C# string functions and other built-in extension methods. You can also filter on classes and properties to apply the attributes selectively.
-
Filter can be on more than one line.
[attribute_name]
#Scope can be dropped for properties
Scope= class
Format=[DataContract]
#apply only on classes the start with 'A'
Filter= ClassName.StartsWith('A')
Complete demo Example:
file: attributes.txt
# file Name: attributes.txt
[map]
Scope= class
Format= [AdaptTo("[name]Dto")]
#apply attribute on classes that have the condition Name StartsWith("A")
Filter= Name.StartsWith("A")
[json4]
Format=[JsonProperty ("{{PropName.ToCamelCase()}}")]
The commandLine:
o2pgen -r https://services.odata.org/TripPinRESTierService ^
--att-defs attributes.txt -a map json4
Output result: Note: only classes Airline and Airport have attribute and all properties with jsonProperty camelCase
Click to expand!
namespace Trippin
{
// EntitySetName: People
public partial class Person
{
[JsonProperty ("userName")]
public string UserName {get;set;} //PrimaryKey not null
[JsonProperty ("firstName")]
public string FirstName {get;set;} // not null
[JsonProperty ("lastName")]
public string LastName {get;set;}
[JsonProperty ("middleName")]
public string MiddleName {get;set;}
[JsonProperty ("gender")]
public PersonGender Gender {get;set;} // not null
[JsonProperty ("age")]
public long Age {get;set;}
[JsonProperty ("emails")]
public List<string> Emails {get;set;}
[JsonProperty ("addressInfo")]
public List<Location> AddressInfo {get;set;}
[JsonProperty ("homeAddress")]
public Location HomeAddress {get;set;}
[JsonProperty ("favoriteFeature")]
public Feature FavoriteFeature {get;set;} // not null
[JsonProperty ("features")]
public List<Feature> Features {get;set;}
}
// EntitySetName: Airlines
[AdaptTo("[name]Dto")]
public partial class Airline
{
[JsonProperty ("airlineCode")]
public string AirlineCode {get;set;} //PrimaryKey not null
[JsonProperty ("name")]
public string Name {get;set;}
}
// EntitySetName: Airports
[AdaptTo("[name]Dto")]
public partial class Airport
{
[JsonProperty ("name")]
public string Name {get;set;}
[JsonProperty ("icaoCode")]
public string IcaoCode {get;set;} //PrimaryKey not null
[JsonProperty ("iataCode")]
public string IataCode {get;set;}
[JsonProperty ("location")]
public AirportLocation Location {get;set;}
}
// Complex Entity
public partial class Location
{
[JsonProperty ("address")]
public string Address {get;set;}
[JsonProperty ("city")]
public City City {get;set;}
}
// Complex Entity
public partial class City
{
[JsonProperty ("name")]
public string Name {get;set;}
[JsonProperty ("countryRegion")]
public string CountryRegion {get;set;}
[JsonProperty ("region")]
public string Region {get;set;}
}
// Complex Entity
[AdaptTo("[name]Dto")]
public partial class AirportLocation : Location
{
[JsonProperty ("loc")]
public GeographyPoint Loc {get;set;}
}
// Complex Entity
public partial class EventLocation : Location
{
[JsonProperty ("buildingInfo")]
public string BuildingInfo {get;set;}
}
// EntitySetName: Trip
public partial class Trip
{
[JsonProperty ("tripId")]
public int TripId {get;set;} //PrimaryKey not null
[JsonProperty ("shareId")]
public Guid ShareId {get;set;} // not null
[JsonProperty ("name")]
public string Name {get;set;}
[JsonProperty ("budget")]
public float Budget {get;set;} // not null
[JsonProperty ("description")]
public string Description {get;set;}
[JsonProperty ("tags")]
public List<string> Tags {get;set;}
[JsonProperty ("startsAt")]
public DateTimeOffset StartsAt {get;set;} // not null
[JsonProperty ("endsAt")]
public DateTimeOffset EndsAt {get;set;} // not null
}
// EntitySetName: PlanItem
public partial class PlanItem
{
[JsonProperty ("planItemId")]
public int PlanItemId {get;set;} //PrimaryKey not null
[JsonProperty ("confirmationCode")]
public string ConfirmationCode {get;set;}
[JsonProperty ("startsAt")]
public DateTimeOffset StartsAt {get;set;} // not null
[JsonProperty ("endsAt")]
public DateTimeOffset EndsAt {get;set;} // not null
[JsonProperty ("duration")]
public TimeSpan Duration {get;set;} // not null
}
// EntitySetName: Event
public partial class Event : PlanItem
{
[JsonProperty ("occursAt")]
public EventLocation OccursAt {get;set;}
[JsonProperty ("description")]
public string Description {get;set;}
}
// EntitySetName: PublicTransportation
public partial class PublicTransportation : PlanItem
{
[JsonProperty ("seatNumber")]
public string SeatNumber {get;set;}
}
// EntitySetName: Flight
public partial class Flight : PublicTransportation
{
[JsonProperty ("flightNumber")]
public string FlightNumber {get;set;}
}
// EntitySetName: Employee
public partial class Employee : Person
{
[JsonProperty ("cost")]
public long Cost {get;set;} // not null
}
// EntitySetName: Manager
public partial class Manager : Person
{
[JsonProperty ("budget")]
public long Budget {get;set;} // not null
[JsonProperty ("bossOffice")]
public Location BossOffice {get;set;}
}
public enum PersonGender
{
Male=0,
Female=1,
Unknown=2
}
public enum Feature
{
Feature1=0,
Feature2=1,
Feature3=2,
Feature4=3
}
}
- home
- Announcing V6.0.0
- Features
- Getting started with c# generation
- Http Connection
- Using Parameter file
- User Defined Attributes
- Controlling c# code generation
- Model Filter
- Enable Nullable Reference type of c# 8
- Class with Init-Only Properties (c# 9)
- Generating Constructor
- Record-Type (c# 9)
- Name Map
- Securing Password
- Using Proxy Server
- Using Plugin Attributes
- Developing with OData2Poco
- Examples in dotnetfiddle.net
- CommandLine-Reference
- AttributeExamples
- typescript generation
- Help Screen
- How to
- New Feature 4.2.1
Samples of generated code: