telstra / digitaltwins-codefirst-dotnet Goto Github PK
View Code? Open in Web Editor NEWDigitalTwins
License: Apache License 2.0
DigitalTwins
License: Apache License 2.0
Hi,
Nice job, you made the it definitely easier for developers to start with Azure digital twins. Do you have any plans to register a package on nuget.org?
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
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:
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.
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.
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.
{ typeof(DateTime), "dateTime" },
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 .....
Hi,
You have defined an interface and an abstract class to manage the twins. However, there is no default implementation in the code. Do you have any plans to implement one? Thank you
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:
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:
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()
};
}
}
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.
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:
e.g.
propertyAttribute!.Name ?? info.Name.ToCamelCase()
Also need to fix the Schema override so it works for Telemetry (not just Property).
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.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.