EMF-JSON: Include properties of EObject Subclass - jackson

I am using EMF-JSON for serializing an EMF model instance. The problem is, that a subclass of EObject gets treated as such and not as the subclass. Thus, properties in the subclass get lost during serialization, as the EObjectSerializer is selected. How can I make sure that the properties of the subclass are included without changing the class itself (referring to the inclusion annotations)? In the following you find the generated interfaces. In this case, the ref property of the ArithVar class is not serialized.
public interface ArithExpr extends EObject {}
public interface ArithVar extends ArithExpr {
VarType getRef();
void setRef(VarType value);
}
public interface VarType extends EObject {}
Any ideas?

From the documentation:
References are by default serialized as JSON objects that contain two fields. The first field is the type of the referenced object and the second field is the URI of the referenced object. The type field is named eClass and the URI field is named $ref.
So my guess is it should work by default. Have you tried debugging through EObjectSerializer ? My guess is it probably uses the EMF reflective API to iterate through all the features of an EObject and serialize them.

Related

In ASPNetCore 2.2, Startup.cs, the Configure property only has {get}, yet it is assigned a reference. Why is this? [duplicate]

I created an automated property:
public int Foo { get; }
This is getter only.
But when I build a constructor, I can change the value:
public MyClass(string name)
{
Foo = 5;
}
Why is it possible, even though this is get-only?
This is a new C# 6 feature, "Getter-only auto-properties", also known as "Auto-Property Initializers for Read-Only Properties" as discussed in this MSDN magazine article 'C# : The New and Improved C# 6.0' by Mark Michaelis and in the C# 6.0 draft Language Specification.
The read-only field's setter is only accessible in the constructor, in all other scenarios the field is still read only and behaves as before.
This is a convenience syntax to reduce the amount of code you need to type and to remove the need to explicitly declare a private module level variable to hold the value.
This feature was seen as important as, since the introduction of Auto-Implemented Properties in C#3, mutable properties (those with a getter and setter) had become quicker to write than immutable ones (those with only a getter), meaning people were being tempted to use mutable properties to avoid having to type the code for a backing field usually required for read-only properties. There is more discussion of Auto-Implemented properties in the relevant section of the Microsoft C# Programming Guide.
This blog post, '#1,207 – C# 6.0 – Auto-Property Initializers for Read-Only Properties' by Sean Sexton Has a good explanation and example as follows:
Prior to C# 6.0, if you wanted a read-only (immutable) property, you’d
typically use a read-only backing field that is initialized in the
constructor, as shown below.
public class Dog
{
public string Name { get; set; }
// DogCreationTime is immutable
private readonly DateTime creTime;
public DateTime DogCreationTime
{
get { return creTime; }
}
public Dog(string name)
{
Name = name;
creTime = DateTime.Now;
}
}
In C# 6.0, you can use auto-implemented properties to implement a
read-only property. You do this by using an auto-property
initializer. The result is much cleaner than the above example, where
we had to explicitly declare a backing field.
public class Dog
{
public string Name { get; set; }
// DogCreationTime is immutable
public DateTime DogCreationTime { get; } = DateTime.Now;
public Dog(string name)
{
Name = name;
}
}
More details can also be found in the dotnet Roslyn repo on GitHub:
Auto-properties can now be declared without a setter.
The backing field of a getter-only auto-property is implicitly
declared as readonly (though this matters only for reflection
purposes). It can be initialized through an initializer on the
property as in the example above. Also, a getter-only property can be
assigned to in the declaring type’s constructor body, which causes the
value to be assigned directly to the underlying field:
This is about expressing types more concisely, but note that it also
removes an important difference in the language between mutable and
immutable types: auto-properties were a shorthand available only if
you were willing to make your class mutable, and so the temptation to
default to that was great. Now, with getter-only auto-properties, the
playing field has been leveled between mutable and immutable.
and in the C# 6.0 draft Language Specification (NB: The language specification is final as far as Microsoft are concerned, but it is yet to be approved as a EMCA/ISO standard, hence the 'draft'):
Automatically implemented properties
An automatically implemented property (or auto-property for short), is
a non-abstract non-extern property with semicolon-only accessor
bodies. Auto-properties must have a get accessor and can optionally
have a set accessor.
When a property is specified as an automatically implemented property,
a hidden backing field is automatically available for the property,
and the accessors are implemented to read from and write to that
backing field. If the auto-property has no set accessor, the backing
field is considered readonly (Readonly fields). Just like a readonly
field, a getter-only auto-property can also be assigned to in the body
of a constructor of the enclosing class. Such an assignment assigns
directly to the readonly backing field of the property.
An auto-property may optionally have a property_initializer, which is
applied directly to the backing field as a variable_initializer
(Variable initializers).
This is a new feature in C#6 that allows you to create read-only properties and initialize their values from the constructor (or inline when you declare them).
If you try to change the value of this property outside the constructor, it would give you a compile error.
It is read-only in the sense that once you initialize its value (inline or inside the constructor), you cannot change its value.
If it were not possible to initialize the read-only property from the constructor (or an auto-property initializer), then it would be useless, since it would always return the default value for its type (0 for numerics, null for reference types). The same semantics applied to readonly fields in all C# versions.
To define a true getter-only property (that cannot be initialized from the constructor), you need to specify what it returns as part of the definition:
public int Foo { get { return 5; } }
Or, more concisely in C# 6:
public int Foo => 5;
“readonly automatically implemented properties”
First of all I want to clarify that the property like
public string FirstName { get; }
Is known as “readonly automatically implemented properties”
To verify this you can run & check the above code with Visual Studio. If you change the language version from C#6.0 to C#5.0 then compiler will throw the following exception
Feature 'readonly automatically implemented properties' is not available in C# 5. Please use language version 6 or greater.
to change C# language version visit here
Now I am coming to your second question
“This is getter only. But when I build a constructor, I can change the value”
Microsoft introduces the “readonly automatically implemented properties” on the logic of read only. As we know that the keyword “readonly” is available from C#1.0. we use “readonly” keyword as modifier on a field and that field can be assigned in 2 ways either at the time of declaration or in a constructor in the same class.
In the same way value of “readonly automatically implemented properties” can be assigned in 2 ways
Way1 (at the time of declaration):
public string FirstName { get; } = "Banketeshvar";
Way2 (in a constructor in the same class)
Person()
{
FirstName = "Banketeshvar";
}
Purely ReadOnly Property
If you are looking for purely Readonly property then go for this
public string FullName => "Manish Sharma";
now you cannot assign value of “FullName” propery from constructor.
If you try to do that it will throw the following exceptions
“Property or indexer 'Person.FullName' cannot be assigned to -- it is read only”
Auto property feature was added to the language during C# 3.0 release. It allows you to define a property without any backing field, however you still need to use constructor to initialize these auto properties to non-default value. C# 6.0 introduces a new feature called auto property initializer which allows you to initialize these properties without a constructor like Below:
Previously, a constructor is required if you want to create objects
using an auto-property and initialize an auto-property to a
non-default value like below:
public class MyClass
{
public int Foo { get; }
public Foo(int foo)
{
Foo = foo;
}
}
Now in C# 6.0, the ability to use an initializer with the auto-property
means no explicit constructor code is required.
public string Foo { get; } = "SomeString";
public List<string> Genres { get; } = new List<string> { "Comedy", "Drama" };
You can find more information on this here
A variable declared readonly can be written within a constructor, but in languages which honor the attribute, cannot be modified after the constructor returns. That qualifier was provided as a language feature because it is often necessary for fields whose values will vary based upon constructor parameters (meaning they can't be initialized before the constructor starts) but won't have to change after constructors return, but it was only usable for variables exposed as fields. The semantics of readonly-qualified fields would in many cases have been perfect for public members except that it's often better for classes to expose members--even immutable ones--as properties rather than fields.
Just as read-write auto-properties exist to allow classes to expose mutable properties as easily as ordinary fields, read-only auto-properties exist to allow classes to expose immutable properties as easily as readonly-qualified fields. Just as readonly-qualified fields can be written in a constructor, so too with get-only properties.

In protobuf-net, is there a way to specify a custom method to be used when serializing/deserializing a given type?

In protobuf-net (Marc Gravell implementation), is there a way to specify a custom Serializer/Deserializer to be used everytime protobuf encouters a type to be serialized ?
Something like that :
[ProtoContract]
class Foo
{
[ProtoMember(1), ProtoSerializer(BarSerializer)]
public Bar Something { get; set; }
}
class BarSerializer
{
public void Serialize(object value, Protowriter writer)
{
//do something here with writer...
}
}
I looked at the docs but could not find anything.
I know this is possible to use Protowriter directly to serialize an object (like this DataTable example).
What I would like to do is to use the custom serializer only for a given type and use default implementation for the other types already implemented (eg : int, string, ...)
No, basically. But what you can do is write a second type (a surrogate type) that is used for serialization. This type needs to have conversion operators between the two types (declared on either, usually the surrogate), and be registered into the library, for example:
RuntimeTypeModel.Default[typeof(Foo)].SetSurrogate(typeof(FooSurrogate));
The library still controls how FooSurrogate is written on the wire. There is not currently an API that allows you to directly control the output inside a type. But if you start from ProtoWriter you can of course do everything manually.

asp.net c# Automap a class from within that class

To best describe what I want to happen, i'll show what i'm doing, as to me it makes sense that this would work ...
public class foo()
{
public foo()
{
MyContext db = new MyContext();
foobar = db.foobar.first();
this = Mapper.Map<bar, foo>(foobar);
}
}
Basically, I want to use automapper within the destination class to map from the source class within the destination classes constructor.
Is there a way to do this?
You cannot do this because this is read only in C#. You cannot assign this a value in the constructor. Not cool to try to change the reference of an object in its constructor. You will have to do the mapping manually and assign each individual property. I would also question if it as a good practice to assign an object values from a database or service in a default constructor. It is not very transparent to the user of the object what is going on and you can get an exception in your constructor.

How can I make some members available to only one object?

I have an EggSac object which contains references to >100 000 Egg objects. Some variables in the Eggs have to be maintained to be consistent with EggSac, so I want to make these only changeable by EggSac. However EggSac passes references to its Eggs all over the application, so if I use public methods then any other code could modify the secure parts of the Eggs by accident.
What's a proper OO way to make sure only the EggSac object can call the "secure" methods of the Eggs, but still make the "safe" methods available to everyone?
My idea is to split Egg's class into a base class containing only safe methods and a derived class containing the secure methods that only EggSac should have access to. Then EggSac has members of the type of the derived class, but it casts them to their base class whenever something else wants one.
Have EggSack hold references to EggImpl, which implements all the necessary methods. Then pass around wrappers over the impl (the Egg class) which only call the "safe" methods on the impl.
When you say security, do you mean avoiding accidental code modification?
A structured way can be something like below.
If you want to make it really 'secure', then you can modify the code to store a string*HashCode* inside the calling class and only if it's matched (inside called ) in Egg, modification is allowed.
Interface ISecureModifier
{
String GetSecureModifierKEY();
String GetSecureModifierVALUE();
}
class Egg
{
Dictionary Secure_ata;
public secureDataModifier( ISecureModifier modifyingObject)//note the interface being used
{
//Here, try a cast (if your compiler still allowed other type objects not implementing ISecureModifier ) and throw exception stating not authorized to modify.
modifyingObject.GetSecureModifierKEY
modifyingObject.GetSecureModifierValue
/*Now write the code to modify Dictionary*/
}
}
class EggSac:ISecureModifier//implements interface
{
private string SecureModifierKEY;
private string SecureModifierVALUE
String GetSecureModifierKEY()//inteface impl
{
return SecureModifierKEY;
}
String GetSecureModifierVALUE();//interface impl
{
return SecureModifierVALUE;
}
ModifySecureData(Egg egg, string key, string value)
{
egg.secureDataModifier(this);//passing own reference
}
}
You may call like this
objEggSack.ModifySecureData(objEgg101, "firstKey","NewValue")

WCF - serializing inherited types

I have these classes:
[DataContract]
public class ErrorBase {}
[DataContract]
public class FileMissingError: ErrorBase {}
[DataContract]
public class ResponseFileInquiry
{
[DataMember]
public List<ErrorBase> errors {get;set;};
}
An instance of the class ResponseFileInquiry is what my service method returns to the client. Now, if I fill ResponseFileInquiry.errors with instances of ErrorBase, everything works fine, but if I add an instance of inherited type FileMissingError, I get a service side exception during serialization:
Type 'MyNamespace.FileMissingError' with data contract name 'FileMissingError'
is not expected. Add any types not known statically to the list of known types -
for example, by using the KnownTypeAttribute attribute or by adding them to the
list of known types passed to DataContractSerializer.'
So serializer is getting confused because it's expecting the List to contain the declared type objects (ErrorBase) but it's getting inherited type (FileMissingError) objects.
I have the whole bunch of error types and the List will contain combinations of them, so what can I do to make it work?
You should add KnownType attribute to your base class
[DataContract]
[KnownType(typeof(FileMissingError))]
public class ErrorBase {}
Read more about KnownType attribute in this blog
Try this:
[DataContract]
[KnownType(typeof(FileMissingError))]
public class ErrorBase {}
As the error message states, any information that cannot be know statically (like the polymorphic relationship you have expressed here) must be supplied via attributes. In this case you need to specify that your FileMissingError data contract is a known type of its base class, ErrorBase.
A tad bit late, but maybe for future generations. =)
If you don't want to add an attribute for every child class to your parent class, you could construct a list of known types in the parent classes static constructor using
IEnumerable<Assembly> assemblies = AppDomain.CurrentDomain
.GetAssemblies()
.Where(a => !a.GlobalAssemblyCache);
IEnumerable<Type> serializableTypes = assemblies.SelectMany(a => a.GetTypes())
.Where(t => IsSerializable(t));
// ...
private static bool IsSerializable(Type type)
{
return type.GetCustomAttributes(true).Any(a => a is DataContractAttribute);
}
and pass this list to the de/serializers constructor. I don't know how robust this solution is, but that's what I am doing and so far it works. It is a little slow, so make sure to cache the result.