Code Monkey home page Code Monkey logo

digitaltwins-codefirst-dotnet's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

digitaltwins-codefirst-dotnet's Issues

Base class properties are not take into account for model generation

If we define abstract base class to hold some repeated properties for a family of related classes, these properties are not taken into account for generating the derived class model definition. Consider this example

 public abstract class Space : TwinBase
    {
        [TwinProperty]
        public string Name { get; set; }
    }

    [DigitalTwin(Version = 1, DisplayName = "Floor")]
    public class Floor : Space
    {
        [TwinProperty]
        public string Level { get; set; }
    }

    [DigitalTwin(Version = 1, DisplayName = "Room")]
    public class Room : Space
    {
        [TwinProperty]
        public string Number { get; set; }
    }

This will produce this model:

{
  "@id": "dtmi:domain:floor;1",
  "@type": "Interface",
  "@context": "dtmi:dtdl:context;2",
  "displayName": "Floor",
  "contents": [
    {
      "@type": "Property",
      "name": "level",
      "schema": "string"
    }
  ]
}

{
  "@id": "dtmi:domain:room;1",
  "@type": "Interface",
  "@context": "dtmi:dtdl:context;2",
  "displayName": "Room",
  "contents": [
    {
      "@type": "Property",
      "name": "number",
      "schema": "string"
    }
  ]
}

The Name property is missing. If I decorate the base class with DigitalTwin attribute, still I don't get the shared properties in the output, however the model has a new part which says it is extending another model (the base class model). But then there is a new problem, when I try to create the model for the base class, I get this error:

System.MissingMethodException : Cannot create an abstract class.

  Stack Trace: 
RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean wrapExceptions, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& hasNoDefaultCtor)
RuntimeType.CreateInstanceDefaultCtorSlow(Boolean publicOnly, Boolean wrapExceptions, Boolean fillCache)
RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, Boolean wrapExceptions)
Activator.CreateInstance(Type type, Boolean nonPublic, Boolean wrapExceptions)
Activator.CreateInstance(Type type)
DigitalTwinSerializer.SerializeModel(Type twinType, Boolean htmlEncode, JsonSerializerOptions serializerOptions) line 119
TwinSerialization_Tests.ShouldSerialiseModelToDTDL(Type type) line 39

DisplayName property on TwinRelationshipAttribute doesn't work

Using the display name attribute as part of a relationship, e.g.

       [TwinRelationship(DisplayName = "Runs Production Lines", MaxMultiplicity = 500)]
        public IList<ProductionLine> RunsLines { get; } = new List<ProductionLine>();

Causes the following error in the ModelParser:

  1. dtmi:factoryexample:models:factoryfloor;1 has 'contents' value with name 'runsLines' which does not have a @type that allows property 'DisplayName'. Remove property 'DisplayName' or correct if misspelled.

The generated DTDL is:

    {
      "DisplayName": "Runs Production Lines",
      "maxMultiplicity": 500,
      "minMultiplicity": 0,
      "target": "dtmi:factoryexample:models:productionline;1",
      "@type": "Relationship",
      "name": "runsLines"
    },

The capitalisation of displayName is incorrect; in the specification it is camelCase, like the other properties.

Primary branch should be called "main"

Using the name "main" is now the default in most tools, as it avoids problematic language and is more in line with most companies social policies.

Can an admin on the repository please change the primary branch name (for merges, etc) to "main", and remove the old problematic branch. This is a very simple operation.

Issue with DateTime property type and nullables

Hi,
I am experimenting with the library and appreciate a lot your project. I found two issues during my experiment and also found the fix.

  • Properties with type of DateTime will end up with no schema in the output DTDL model. To address the issue, we need to add the missing type map in ModelProperty.Factory.cs for SchemaMap variable { typeof(DateTime), "dateTime" },
  • Nullable properties seems to be working fine, however a nullable of DateTime still will have no schema in the output. To fix it, in the same file, I made these changes:

internal static object SchemaFromType(PropertyInfo info)
{
var propertyType = info.PropertyType;
var nullableType = Nullable.GetUnderlyingType(propertyType);
if (SchemaMap.ContainsKey(propertyType))
return SchemaMap[propertyType];
else if(nullableType != null && SchemaMap.ContainsKey(nullableType))
{
return SchemaMap[nullableType];
}

else if .....

Semantic type and units are not working

A telemetry type attribute with Unit and SemanticType does not work.

Example property:

        [TwinTelemetry(Unit = "degreeCelsius", SemanticType = "Temperature")]
        public double? Temperature { get; set; }

Validating with the model parser gives two errors:

  1. dtmi:factoryexample:models:factoryfloor;1 has 'contents' value with name 'temperature' which does not have a @type that allows property 'SemanticType'. Remove property 'SemanticType' or correct if misspelled.
  2. dtmi:factoryexample:models:factoryfloor;1 has 'contents' value with name 'temperature' which does not have a @type that allows property 'Unit'. Remove property 'Unit' or correct if misspelled.

The generated DTDL that caused the error is:

    {
      "SemanticType": "Temperature",
      "Unit": "degreeCelsius",
      "@type": "Telemetry",
      "name": "temperature",
      "schema": "double"
    }

According to the DTDLv2 specification, it should be the following (See examples at: https://github.com/Azure/opendigitaltwins-dtdl/blob/master/DTDL/v2/dtdlv2.md#telemetry-examples)

    {
      "@type": ["Telemetry", "Temperature"],
      "name": "temperature",
      "schema": "double",
      "unit": "degreeCelsius"
    }

Other things to note:

  • Semantic types should also apply to Properties (not just Telemetry).
  • The list of valid semantic types and units is in the DTDLv2 specification

OutPut model always will set the max/minMultiplicity for relations even if you don't set on the attribute

Hi,
When I place a Relation attribute on a non-collection property of a class without initializing the Max/MinMultiplicity, I get these with default value of 0 in the output models. However the maxMultiplicity = 0 is not allowed by the DTDL definition and the minMultiplicity is by default 0 if you don't set it. Due to the issue that in C# attribute properties can not be nullable, I made these changes to not include them when the value is 0 which will fix the problem.

considering this model:

[DigitalTwin(Version=1,DisplayName="Twin with a relationship")]
    public class TwinWithRelationship: TwinBase
    {

        [TwinProperty]
        public int Count { get; set; }

        //[TwinRelationship(Name = "Test Relationship", MaxMultiplicity = 5)] // I have commendted this one
        [TwinRelationship(Name = "Test Relationship")] // this one has no max/min 
        public SimpleTwin Relationship { get; set;} 
    }

you can see the issue here in this model:

{
      "@id": "dtmi:telstra:twins:test:twinwithrelationship;1",
      "@type": "Interface",
      "@context": "dtmi:dtdl:context;2",
      "displayName": "Twin with a relationship",
      "contents": [
        {
          "@type": "Property",
          "name": "count",
          "schema": "integer"
        },
        {
          "maxMultiplicity": 0,
          "minMultiplicity": 0,
          "target": "dtmi:telstra:twins:test:simpletwin;1",
          "@type": "Relationship",
          "name": "relationship"
        }
      ]
    }
public partial class ModelRelationship : Content
    {
        public static ModelRelationship Create(PropertyInfo info)
        {
            var attr = info.GetCustomAttribute<TwinRelationshipAttribute>();

            return new ModelRelationship(info.Name.ToCamelCase())
            {
                DisplayName = attr.DisplayName,
                Comment = attr.Comment,
                Description = attr.Description,
                MaxMultiplicity = attr.MaxMultiplicity **== 0 ? null : attr.MaxMultiplicity**,
                MinMultiplicity = attr.MinMultiplicity **== 0 ? null : attr.MinMultiplicity**,
                Target = info.PropertyType.GetModelPropertyType().GetDigitalTwinModelId()
            };
        }
    }

Library does not appear available on Nuget

There was a previous issue #1 by @mahdighorbanpour that asked this question and was told on 17 November "will be available on Nuget latest by next week". It was then closed by the original requester (which is fair enough), but I can't find the library. There is a comment by @dmaxwell that they can't find it either.

When the library is available on Nuget, can the Readme please be updated with a link to the location / the package name & instructions how to add it.

Keep this issue open until it is available.

The `name` property in attributes is not recognised in the generated model

This affects properties/telemetry, components, and relationships, all of which have a name property.

e.g. Using the following code:

        [TwinRelationship(Name = "rel_runs_lines", DisplayName = "Runs Production Lines")]
        public IList<ProductionLine> RunsLines { get; } = new List<ProductionLine>();

The serialization outputs with the name runsLines instead of rel_runs_lines as expected:

    {
      "target": "dtmi:factoryexample:models:productionline;1",
      "name": "runsLines",
      "@type": "Relationship",
      "displayName": "Runs Production Lines"
    }

The output should have "name": "rel_runs_lines"

The fix is:

  1. to first add some unit tests,
  2. then to override if the attribute property is set, similar to how Schema is handled. Make it consistent across the different attributes

e.g.

propertyAttribute!.Name ?? info.Name.ToCamelCase()

Also need to fix the Schema override so it works for Telemetry (not just Property).

Remove old Newtonsoft references (if no longer used)

The code includes references and attributes for both the current System.Text.Json and also the older (deprecate) Newtonsoft.Json.

It appears that the standard System.Text.Json is the library used to actually convert to/from JSON.

The references to Newtonsoft can be removed.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.