@@ -7,6 +7,7 @@ namespace Optimizely.Graph.Client.Tools
77public class Program
88{
99private static string USER_AGENT => $ "Optimizely-Graph-Tools/{ typeof ( Program ) . Assembly . GetName ( ) . Version } ";
10+ private static Dictionary < string , string > ExtensionMethodKeyPair = new Dictionary < string , string > ( ) ; //method name - class type
1011static void Main ( string [ ] args )
1112{
1213Console . WriteLine ( "**** Optimizely Content Graph Client Tools ****" ) ;
@@ -66,6 +67,10 @@ static void Main(string[] args)
6667output = Path . Combine ( di . FullName , defaultFileName ) ;
6768}
6869}
70+ else
71+ {
72+ output = Path . Combine ( Directory . GetCurrentDirectory ( ) , defaultFileName ) ;
73+ }
6974
7075if ( args . Length > 2 )
7176{
@@ -111,6 +116,8 @@ public static void Run(IConfiguration configuration,
111116
112117Console . WriteLine ( "Writing files..." ) ;
113118var sb = new StringBuilder ( ) ;
119+ var extensionBuilder = new StringBuilder ( ) ;
120+
114121sb . AppendLine ( "using System;" ) ;
115122sb . AppendLine ( "using System.Collections.Generic;" ) ;
116123sb . AppendLine ( "using EPiServer.Core;" ) ;
@@ -123,6 +130,8 @@ public static void Run(IConfiguration configuration,
123130sb . AppendLine ( "namespace " + modelNamespace ) ;
124131sb . AppendLine ( "{" ) ;
125132
133+ BeginExtension ( modelNamespace , extensionBuilder ) ;
134+
126135foreach ( JProperty propertyType in propertyTypes )
127136{
128137var propertyTypeName = propertyType . Name ;
@@ -134,12 +143,14 @@ public static void Run(IConfiguration configuration,
134143
135144foreach ( JProperty propertyProperty in properties )
136145{
146+ var enumProps = new List < string > ( ) ;
137147var name = propertyProperty . Name ;
138148var dataType = ( propertyProperty . Children ( ) [ "type" ] . First ( ) as JValue ) . Value . ToString ( ) ;
139- dataType = ConvertType ( dataType ) ;
149+ dataType = ConvertType ( dataType , out var typeExtension ) ;
140150sb . Append ( $ " public{ dataType } { name } ") ;
141151sb . AppendLine ( "{ get; set; }" ) ;
142152
153+ BuildExtensionMethods ( typeExtension , name , propertyTypeName , extensionBuilder ) ;
143154}
144155
145156sb . AppendLine ( " }" ) ;
@@ -153,7 +164,8 @@ public static void Run(IConfiguration configuration,
153164
154165if ( parentTypes != null && parentTypes . Count ( ) > 0 )
155166{
156- inheritedFromType = string . Join ( ',' , parentTypes . Select ( type=> type . ToString ( ) ) ) ;
167+ //inheritedFromType = string.Join(',', parentTypes.Select(type=> type.ToString()));
168+ inheritedFromType = parentTypes . Select ( type=> type . ToString ( ) ) . First ( ) ;
157169inheritedFromType = $ ":{ inheritedFromType } ";
158170}
159171sb . AppendLine ( $ " public partial class{ propertyTypeName } { inheritedFromType } ") ;
@@ -166,7 +178,8 @@ public static void Run(IConfiguration configuration,
166178var name = propertyProperty . Name ;
167179var searchableAttr = ( bool ) ( ( propertyProperty . Children ( ) [ "searchable" ] . FirstOrDefault ( ) as JValue ) ? . Value ?? false ) ;
168180var dataType = ( propertyProperty . Children ( ) [ "type" ] . First ( ) as JValue ) . Value . ToString ( ) ;
169- dataType = ConvertType ( dataType ) ;
181+ dataType = ConvertType ( dataType , out var typeExtension ) ;
182+ BuildExtensionMethods ( typeExtension , name , propertyTypeName , extensionBuilder ) ;
170183if ( searchableAttr )
171184{
172185sb . AppendLine ( $ " [Searchable]") ;
@@ -175,12 +188,19 @@ public static void Run(IConfiguration configuration,
175188sb . AppendLine ( "{ get; set; }" ) ;
176189
177190}
178-
191+ //add system properties
192+ //sb.AppendLine("[JsonProperty(\"_id\")]");
193+ //sb.AppendLine("public string Id { get;set; }");
194+ //end system properties
179195sb . AppendLine ( " }" ) ;
180196}
181197
198+ EndExtension ( extensionBuilder ) ;
182199
183200sb . AppendLine ( "}" ) ;
201+ //append extension to file
202+ sb . AppendLine ( "//Extension methods" ) ;
203+ sb . Append ( extensionBuilder ) ;
184204var classes = sb . ToString ( ) ;
185205FileInfo fi = new FileInfo ( output ) ;
186206// Check if directory exists, create if not
@@ -196,41 +216,47 @@ public static void Run(IConfiguration configuration,
196216Console . WriteLine ( $ "Optimizely Graph model C# classes have been written to{ output } .") ;
197217}
198218
199- private static string ConvertType ( string propType )
219+ private static string ConvertType ( string propType , out string typeExtension )
200220{
201221bool isIEnumerable = false ;
222+ bool isComplexType = false ;
223+ typeExtension = string . Empty ;
224+
202225if ( propType . StartsWith ( "[" ) && propType . EndsWith ( "]" ) ) //Is IEnumerable
203226{
204227propType = propType . Substring ( 1 , propType . Length - 2 ) ;
205228isIEnumerable = true ;
206229}
207- if ( propType . Equals ( "Date" ) )
208- {
209- propType = "DateTime" ;
210- }
211- if ( propType . Equals ( "Bool" ) || propType . Equals ( "Boolean" ) )
212- {
213- propType = "bool" ;
214- }
215- if ( propType . Equals ( "String" ) )
216- {
217- propType = "string" ;
218- }
219- if ( propType . Equals ( "LongString" ) )
220- {
221- propType = "string" ;
222- }
223- if ( propType . Equals ( "Int" ) )
224- {
225- propType = "int" ;
226- }
227- if ( propType . Equals ( "Float" ) )
230+
231+ switch ( propType )
228232{
229- propType = "float" ;
233+ case "Date" :
234+ propType = "DateTime" ;
235+ break ;
236+ case "Bool" :
237+ propType = "bool" ;
238+ break ;
239+ case "Boolean" :
240+ propType = "bool" ;
241+ break ;
242+ case "String" :
243+ propType = "string" ;
244+ break ;
245+ case "Int" :
246+ propType = "int" ;
247+ break ;
248+ case "Float" :
249+ propType = "float" ;
250+ break ;
251+ default :
252+ isComplexType = true ;
253+ break ;
230254}
255+
231256if ( isIEnumerable )
232257{
233- propType = $ "IEnumerable<{ propType } >";
258+ typeExtension = isComplexType ? propType : string . Empty ;
259+ return $ "IEnumerable<{ propType } >";
234260}
235261
236262return propType ;
@@ -292,6 +318,33 @@ private static Config ReadConfig(IConfiguration configuration)
292318SecretKey = myconfigs . GetSection ( "ContentGraph:Secret" ) . Value
293319} ;
294320}
321+ private static void BeginExtension ( string modelNamespace , StringBuilder builder )
322+ {
323+ builder . AppendLine ( $ "namespace{ modelNamespace } .Extension") ;
324+ builder . AppendLine ( "{" ) ; //begin namespace
325+ builder . AppendLine ( $ " public static class GraphModelsExtension") ;
326+ builder . AppendLine ( " {" ) ; //begin class
327+ }
328+ private static void EndExtension ( StringBuilder builder )
329+ {
330+ builder . AppendLine ( " }" ) ; //end class
331+ builder . AppendLine ( "}" ) ; //end namespace
332+ }
333+ private static void BuildExtensionMethods ( string returnType , string methodName , string classType , StringBuilder builder )
334+ {
335+ if ( ! string . IsNullOrEmpty ( returnType ) )
336+ {
337+ if ( ExtensionMethodKeyPair . ContainsKey ( methodName ) && ExtensionMethodKeyPair [ methodName ] == classType )
338+ {
339+ return ;
340+ }
341+ ExtensionMethodKeyPair . TryAdd ( methodName , classType ) ;
342+ builder . Append ( $ " public static{ returnType } { methodName } (this{ classType } obj) ") ;
343+ builder . AppendLine ( " {" ) ;
344+ builder . AppendLine ( " return null;" ) ;
345+ builder . AppendLine ( " }" ) ;
346+ }
347+ }
295348}
296349internal class Config
297350{