@@ -13,10 +13,10 @@ internal sealed class ContractDefinitionProvider : JsonSchemaDefinitionReader, I
1313 {
1414 #region Fields
1515 private const string RootFolderName = "Contracts" ;
16+ private readonly ITypeResolverFacade _typeResolver ;
1617 private readonly string _productName ;
1718 private readonly string _areaName ;
1819 private readonly IDictionary < string , ContractDefinition > _contracts ;
19- private readonly ICollection < string > _referencedContracts ;
2020 #endregion
2121
2222 #region Properties
@@ -26,13 +26,13 @@ internal sealed class ContractDefinitionProvider : JsonSchemaDefinitionReader, I
2626 #endregion
2727
2828 #region Constructor
29- public ContractDefinitionProvider ( IFileSystemProvider fileSystemProvider , ILogger logger , IEnumerable < string > contracts , string productName , string areaName ) : base ( fileSystemProvider , logger )
29+ public ContractDefinitionProvider ( IFileSystemProvider fileSystemProvider , ITypeResolverFacade typeResolver , ILogger logger , IEnumerable < string > contracts , string productName , string areaName ) : base ( fileSystemProvider , logger )
3030 {
31+ this . _typeResolver = typeResolver ;
3132 this . _productName = productName ;
3233 this . _areaName = areaName ;
3334 this . _contracts = new Dictionary < string , ContractDefinition > ( ) ;
34- this . _referencedContracts = new HashSet < string > ( ) ;
35- this . CollectCore ( contracts ) ;
35+ base . Collect ( contracts ) ;
3636 }
3737 #endregion
3838
@@ -44,8 +44,6 @@ public bool TryGetSchema(string fullName, out SchemaDefinition schema)
4444 schema = null ;
4545 return false ;
4646 }
47-
48- contract . HasReferences = true ;
4947 schema = contract . Schema ;
5048 return true ;
5149 }
@@ -67,34 +65,25 @@ protected override void Read(string filePath, JObject json)
6765 string relativeNamespace = String . Join ( "." , parts . Skip ( 1 ) ) ;
6866 NamespacePath currentNamespace = PathUtility . BuildAbsoluteNamespace ( this . _productName , this . _areaName , LayerName . DomainModel , relativeNamespace ) ;
6967
70- string root = multipleAreas ? parts [ 1 ] : null ;
71- NamespacePath rootNamespace = PathUtility . BuildAbsoluteNamespace ( this . _productName , this . _areaName , LayerName . DomainModel , relativeNamespace : root ) ;
72-
73- this . ReadContracts ( rootNamespace , currentNamespace , json , filePath ) ;
68+ this . ReadContracts ( currentNamespace , relativeNamespace , json , filePath ) ;
7469 }
7570 #endregion
7671
7772 #region Private Methods
78- private void CollectCore ( IEnumerable < string > contracts )
79- {
80- base . Collect ( contracts ) ;
81- this . CollectReferenceCounts ( ) ;
82- }
83-
84- private void ReadContracts ( NamespacePath rootNamespace , NamespacePath currentNamespace , JObject contracts , string filePath )
73+ private void ReadContracts ( NamespacePath currentNamespace , string relativeNamespace , JObject contracts , string filePath )
8574 {
8675 foreach ( JProperty definitionProperty in contracts . Properties ( ) )
8776 {
88- this . ReadContract ( rootNamespace , currentNamespace , definitionProperty . Name , definitionProperty . Value , filePath , definitionProperty . GetLineInfo ( ) ) ;
77+ this . ReadContract ( currentNamespace , relativeNamespace , definitionProperty . Name , definitionProperty . Value , filePath , definitionProperty . GetLineInfo ( ) ) ;
8978 }
9079 }
9180
92- private void ReadContract ( NamespacePath rootNamespace , NamespacePath currentNamespace , string definitionName , JToken value , string filePath , IJsonLineInfo lineInfo )
81+ private void ReadContract ( NamespacePath currentNamespace , string relativeNamespace , string definitionName , JToken value , string filePath , IJsonLineInfo lineInfo )
9382 {
9483 switch ( value . Type )
9584 {
9685 case JTokenType . Object :
97- this . ReadObjectContract ( rootNamespace , currentNamespace , definitionName , value , filePath , lineInfo ) ;
86+ this . ReadObjectContract ( currentNamespace , relativeNamespace , definitionName , value , filePath , lineInfo ) ;
9887 break ;
9988
10089 case JTokenType . Array :
@@ -106,7 +95,7 @@ private void ReadContract(NamespacePath rootNamespace, NamespacePath currentName
10695 }
10796 }
10897
109- private void ReadObjectContract ( NamespacePath rootNamespace , NamespacePath currentNamespace , string definitionName , JToken value , string filePath , IJsonLineInfo lineInfo )
98+ private void ReadObjectContract ( NamespacePath currentNamespace , string relativeNamespace , string definitionName , JToken value , string filePath , IJsonLineInfo lineInfo )
11099 {
111100 ObjectSchema contract = new ObjectSchema ( currentNamespace . Path , definitionName , SchemaDefinitionSource . Defined ) ;
112101 foreach ( JProperty property in ( ( JObject ) value ) . Properties ( ) )
@@ -150,17 +139,34 @@ private void ReadObjectContract(NamespacePath rootNamespace, NamespacePath curre
150139 throw new ArgumentOutOfRangeException ( nameof ( property . Type ) , property . Type , null ) ;
151140 }
152141
153- TypeReference type = this . ParsePropertyType ( typeName , rootNamespace , filePath , typeNameValue ) ;
154- ValueReference defaultValue = null ;
155- if ( defaultValueJson != null )
142+ IJsonLineInfo propertyLineInfo = property . GetLineInfo ( ) ;
143+ Token < string > propertyName = new Token < string > ( property . Name , filePath , propertyLineInfo . LineNumber , propertyLineInfo . LinePosition ) ;
144+
145+ TypeReference ResolveType ( )
156146 {
157- IJsonLineInfo defaultValueLocation = defaultValueJson . GetLineInfo ( ) ;
158- defaultValue = JsonValueReferenceParser . Parse ( type , defaultValueJson , filePath , defaultValueLocation , Logger ) ;
147+ bool isEnumerable = typeName . EndsWith ( "*" , StringComparison . Ordinal ) ;
148+ typeName = typeName . TrimEnd ( '*' ) ;
149+
150+ // TODO: Remove support
151+ typeName = typeName . TrimStart ( '#' ) ;
152+
153+ IJsonLineInfo location = value . GetLineInfo ( ) ;
154+ TypeReference type = this . _typeResolver . ResolveType ( typeName , relativeNamespace , filePath , location . LineNumber , location . LinePosition , isEnumerable ) ;
155+ return type ;
159156 }
160157
161- IJsonLineInfo propertyLineInfo = property . GetLineInfo ( ) ;
162- Token < string > propertyName = new Token < string > ( property . Name , filePath , propertyLineInfo . LineNumber , propertyLineInfo . LinePosition ) ;
163- ObjectSchemaProperty objectSchemaProperty = new ObjectSchemaProperty ( propertyName , type , defaultValue , serializationBehavior , dateTimeKind , isPartOfKey , isOptional , isDiscriminator , isObfuscated , isRelativeHttpsUrl ) ;
158+ ValueReference ResolveDefaultValue ( TypeReference typeReference )
159+ {
160+ ValueReference defaultValue = null ;
161+ if ( defaultValueJson != null )
162+ {
163+ IJsonLineInfo defaultValueLocation = defaultValueJson . GetLineInfo ( ) ;
164+ defaultValue = JsonValueReferenceParser . Parse ( typeReference , defaultValueJson , filePath , defaultValueLocation , Logger ) ;
165+ }
166+ return defaultValue ;
167+ }
168+
169+ ObjectSchemaProperty objectSchemaProperty = new ObjectSchemaProperty ( propertyName , ResolveType , ResolveDefaultValue , serializationBehavior , dateTimeKind , isPartOfKey , isOptional , isDiscriminator , isObfuscated , isRelativeHttpsUrl ) ;
164170 contract . Properties . Add ( objectSchemaProperty ) ;
165171 }
166172 }
@@ -241,47 +247,6 @@ private static EnumValue ReadEnumValue(string name, JValue value, JTokenType typ
241247 default : throw new ArgumentOutOfRangeException ( nameof ( type ) , type , null ) ;
242248 }
243249 }
244-
245- private TypeReference ParsePropertyType ( string typeName , NamespacePath rootNamespace , string filePath , JToken value )
246- {
247- bool isEnumerable = typeName . EndsWith ( "*" , StringComparison . Ordinal ) ;
248- typeName = typeName . TrimEnd ( '*' ) ;
249-
250- bool isNullable = typeName . EndsWith ( "?" , StringComparison . Ordinal ) ;
251- typeName = typeName . TrimEnd ( '?' ) ;
252-
253- bool isTypeReference = typeName . StartsWith ( "#" , StringComparison . Ordinal ) ;
254- typeName = typeName . TrimStart ( '#' ) ;
255-
256- IJsonLineInfo location = value . GetLineInfo ( ) ;
257- if ( isTypeReference )
258- {
259- // TODO: Actually the contracts should have a namespace group, just like the procedures.
260- // The folder itself should not indicate a namespace (just like in C#).
261- // Therefore a namespace property should be added to the contract schema.
262- // This would however introduce a breaking change, since in C#, when you are within a namespace group,
263- // and you want to reference a type from outside of the namespace, an absolute namespace must be used.
264- string key = $ "{ rootNamespace } .{ typeName } ";
265- this . _referencedContracts . Add ( key ) ;
266- return new SchemaTypeReference ( key , isNullable , isEnumerable , filePath , location . LineNumber , location . LinePosition ) ;
267- }
268-
269- PrimitiveType dataType = ( PrimitiveType ) Enum . Parse ( typeof ( PrimitiveType ) , typeName , ignoreCase : true /* JSON is camelCase while C# is PascalCase */ ) ;
270- return new PrimitiveTypeReference ( dataType , isNullable , isEnumerable , filePath , location . LineNumber , location . LinePosition ) ;
271- }
272-
273- private void CollectReferenceCounts ( )
274- {
275- foreach ( string name in this . _referencedContracts )
276- {
277- if ( ! this . _contracts . TryGetValue ( name , out ContractDefinition contractDefinition ) )
278- {
279- // The contract is quite possibly not defined in this project
280- continue ;
281- }
282- contractDefinition . HasReferences = true ;
283- }
284- }
285250 #endregion
286251
287252 #region Nested types
0 commit comments