OData / odata.net

ODataLib: Open Data Protocol - .NET Libraries and Frameworks
https://docs.microsoft.com/odata
Other
687 stars 349 forks source link

strongly typed standard vocabulary APIs #2244

Open chrisspre opened 2 years ago

chrisspre commented 2 years ago

Proposal to create a strongly typed standard vocabulary API as a new separate nuget package.

today the standard vocabulary is exposed through types like Microsoft.OData.Edm.Vocabularies.V1.CapabilitiesVocabularyModel and Microsoft.OData.Edm.Vocabularies.V1.CoreVocabularyModel. But the coverage is sparse; a lot of terms from Core are exposed via C# properties but for Vocabulary only the IEdmModel is provided as a property.

There should be an API that allows to read and write Annotation using strongly typed C# classes. Something along the lines of

model.AddAnnotation(element, new V1.Capabilities.ReadRestrictions{ … } );

and

model.TryGetAnnotation<V1.Capabilities.ReadRestrictions>(element, out var annotation);

or at least through a more generic object model similar to the API's provided by the System.Text.Json.JsonElement or Newtonsoft.Json.Linq.JObject.

The code for that needs to be able to map from IEdmExpression to C# classes (and vice versa) . Such code is very repetitive for different annotation and error prone but completely defined by the CSDL schema for the annotation vocabulary. That means there is an opportunity to generate this code automatically from the vocabulary CSDL files.

xuzhg commented 2 years ago

FYI, we have done something similar on the model builder side. See https://github.com/OData/ModelBuilder/tree/master/src/Microsoft.OData.ModelBuilder/Vocabularies

corranrogue9 commented 2 years ago

Is this something that we can do in 7.x? This work might be dependent on this item: https://github.com/OData/odata.net/issues/2398

chrisspre commented 2 years ago

Yes, I believe it is related. We have some annotations that are strongly typed and can easily be added and read but we are not doing this for all since this implementation is manual. If these types can be generated from annotation CSDL, the maintenance should be less. Since this is additive I thin this can be added to 7.x (but would then need to be maintained in future releases)

corranrogue9 commented 2 years ago

I am adding context from one of our investigations meetings to each of the EDM related work items. Please keep these scenarios in mind when investigating this work item:

It has been suggested (by myself) that removing the EDM interfaces and replacing them with concrete types where appropriate would be a good idea. 2 existing scenarios were enumerated for why the interfaces are necessary, 1 existing scenario was enumerated for why the interfaces are helpful (but not strictly necessary), 1 known future scenario was enumerated for why the interaces continue to be necessary, and 1 potential future scenario was enumerate for why the interfaces provide existensibility that wouldn't be available with concrete types.

Existing necessary scenarios

  1. The interfaces are used today for mocking in unit tests
  2. The interfaces could be used by customers to provide custom implementations for each type

Existing helpful scenarios

  1. It is helpful to have a read-only view into the EDM models

Known future scenario

  1. We want to allow customers to update their models after, for example, the model has been read from a CSDL file. The interfaces being a read-only view give the option for the concrete types to be used for post-read modifications, with the interfaces being used once those modifications are complete.

Potential future scenario

  1. There is a potential scenario where the full model being loaded into memory is not necessary for a customer. With the current structure of the IEdmModel interface, this means that, if all other EDM types were concrete types, then any instance of IEdmModel would necessarily need to load portions of the model into memory even if those portions aren't used. A new implementation of non-model EDM interfaces would allow for this even though the concrete types would not.