I need to ensure the following class is serializable by Microsoft Bond. I am struggling to find a way to do this due to the inclusion of the object member.
public class BondRemotingRequestMessageBody : IServiceRemotingRequestMessageBody
{
public object Value;
public BondRemotingRequestMessageBody()
{
}
public BondRemotingRequestMessageBody(int parameterInfos)
{
}
public void SetParameter(int position, string paramName, object parameter)
{
Value = parameter;
}
public object GetParameter(int position, string paramName, Type paramType)
{
return Value;
}
}
Is there a way around this?
This is for an Azure Service Fabric ASR implementation.
Thanks in advance.
I don't know about the Service Fabric parts, but from a Bond perspective, all of the fields that are to be serialized must be known to Bond and must be a type (or convertible to a type) that can be serialized. In practice, this means that all of the data structures that you need to serialize is expressed in a collection of .bond files.
The closest to C#'s object would be a bonded<bond.Void> field that you later deserialize as the proper well-known derived type. You would need to include (or be able to infer/derive) the correct derived type. The polymorphic container example demonstrates this pattern; it uses an enum field in a base struct to carry the derived type information.
Related
I am new to the angular2 world. I am trying to create interfaces for certain components and then implement these interfaces in my models so I can make sure they will be able to work properly.
One thing I have noticed is that if I create new instances of these objects they work fine but when I pull data from a restful call, I use the type casting to turn the data into the type of object I expect. The following code is a pseudo example.
I come from a Java/C++ background so I am hoping someone can see what I'm trying to do and explain to me how to get this working correctly.
Thanks In Advance!
Doesn't work ---
private vehicles: Vehicle[];
this._vehicleService.loadVehicles().subscribe(
vehicles => this.vehicles = <Vehicle[]>vehicles);
Does Work ---
vehicles : Vehicle[];
vehicles.push(new Vehicle(1, 'Old Junker'));
vehicles.push(new Vehicle(2, 'Old Junker2'));
Example class/interface setup.
#Component
export class SelectableComponent {
options : Selectable[]
// Access options.label and options.value
}
export interface Selectable {
label(): string;
value(): any;
}
export class Vehicle implements Selectable {
constructor (
public id: number,
public description: string,
){}
get label() : any {
return this.description;
}
get value() : any {
return this.id;
}
}
What happens here is that the object retrieved from the backend is just a plain Javascript object that gets cast to a Vehicle:
this._vehicleService.loadVehicles().subscribe(
vehicles => this.vehicles = <Vehicle[]>vehicles);
Objects in this array will have all the data of a Vehicle, but none of the behavior of an instance of the Vehicle class, which can be quite confusing as you mention.
The simplest is instead of casting them, calling new and creating an instance of Vehicle immediately while retrieving them from the backend.
But using a long constructor call can be cumbersome, especially if Vehicle has a lot of properties and you need to pass them all to the constructor one by one.
A way to fix this is to create an auxiliary method in the Vehicle class:
class Vehicle {
constructor(private name, private year) {
}
static fromJson({name,year}) {
return new Vehicle(name, year);
}
}
And then use it in return from the backend to create an array of Vehicles, instead of casting them:
this._vehicleService.loadVehicles().subscribe(
vehicles => this.vehicles = vehicles.map(Vehicle.fromJson));
This way the vehicles in the result will have not only all the data of a vehicle, but also the behavior of the Vehicle class, because they are instances on Vehicle.
The main difference between classes and interfaces in TypeScript is that interfaces don't exist at runtime. They are "only" there for compilation and type checking.
Casting an element to an interface / class "only" tells TypeScript that the object follows the structure of it but it's not actually an instance of the type. It's a bit disturbing at a first sight. The main consequence (in the case of a class) is that casting doesn't allow you to use methods of the class.
I already casted this way:
private vehicles: Vehicle[];
this._vehicleService.loadVehicles().subscribe(
vehicles => this.vehicles = <Vehicle[]>vehicles);
What is the exact compilation error you have?
I believe this is not possible, but I just wanted to verify.
I would like to do something like...
#Path("/awesome")
public class MyRestResource {
#GET
public void coolQuery(#QueryParam("user") User) {
// ...
}
}
public interface User {
String name();
Address address();
}
(Please don't comment on the example... it's completely made-up and not my use case.)
I imagine this is not possible because Jersey/JAX-RS generally requires a static method public static T valueOf(String input) which obviously is not possible with interfaces.
That said, is there any work-around for this to have a query parameter be an interface? And if so, how do you specify the parser / parsing logic?
Thanks
According to the documentation there are more ways than just the static valueOf method:
Be a primitive type;
Have a constructor that accepts a single String argument;
Have a static method named valueOf or fromString that accepts a single String argument (see, for example, Integer.valueOf(String) and java.util.UUID.fromString(String));
Have a registered implementation of javax.ws.rs.ext.ParamConverterProvider JAX-RS extension SPI that returns a javax.ws.rs.ext.ParamConverter instance capable of a "from string" conversion for the type. or
Be List<T>, Set<T> or SortedSet<T>, where T satisfies 2 or 3 above. The resulting collection is read-only.
The solution using a ParamConverterProvider should work in this case.
I have an object like so:
public class Intent
{
public List<Entity> Updates { get; set; }
}
Which I wish to serialize into XML for passing as a message using MSMQ. The list of type Entity can contain any number of instances of classes that inherit from Entity. For example, there may be:
public Person : Entity { /* ... */ }
public Vehicle : Entity { /* ... */ }
I'm using XmlMessageFormatter, which so far I have defined as:
XmlMessageFormatter _formatter =
new XmlMessageFormatter(new[] { typeof(T) });
Where T in this instance is Intent (as above).
Trouble is, when the code actually attempts to serialize the following exception occurs:
The type CoreApi.Domain.Person was not expected. Use the XmlInclude or SoapInclude attribute to specify types that are not known statically.
I believe this is because I need to tell the serializer somehow of the fact that Person is a child class of entity.
I've seen solutions that basically entail adorning Entity with multiple XmlInclude decorations, which in my scenario is unworkable as the list of inheritors of Entity is large and could grow - I don't want to constantly update this list as new inheritors are added.
I've seen other solutions that use XmlSerializer, passing in a list of known types, the trouble with this is that I somehow need to replace XmlMessageSerialiser with the XmlSerialiser instance which isn't compatible.
i have a question.i have a method (Filter),i want to pass T dynamic.but it dosen`t accept.how can i do it?
public List<T> Filter<T>(string TypeOfCompare)
{
List<T> ReturnList2 = new List<T>();
return ReturnList2;
}
IList MakeListOfType(Type listType)
{
Type listType1 = typeof(List<>);
Type specificListType = listType.MakeGenericType(listType1);
return (IList)Activator.CreateInstance(specificListType);
}
Filter < ConstructGenericList(h) > ("s");
IList MakeListOfType(Type listType)
{
Type listType1 = typeof(List<>);
Type specificListType = listType.MakeGenericType(listType1);
return (IList)Activator.CreateInstance(specificListType);
}
It should be the other way round, you should call MakeGenericType on the generic type definition, not on the generic type argument. So the code becomes this:
IList MakeListOfType(Type elementType)
{
Type listType = typeof(List<>);
Type specificListType = listType.MakeGenericType(elementType);
return (IList)Activator.CreateInstance(specificListType);
}
(note that I changed the variables names to make the code clearer)
Generic parameters must have a type able to be determined at compile time (without resorting to something like functional type inference that some other languages have). So, you can't just stick a function between the angle brackets to get the type you want.
Edit:
Now that I know what you're trying to do, I would suggest a different approach entirely.
You mention that you are using Entity Framework, and you are trying to use one method to get a list of different types of objects. Those objects -- like Student and Teacher -- must have something in common, though, else you would not be trying to use the same method to retrieve a list of them. For example, you may just be wanting to display a name and have an ID to use as a key.
In that case, I would suggest defining an interface that has the properties common to Student, Teacher, etc. that you actually need, then returning a list of that interface type. Within the method, you would essentially be using a variant of the factory pattern.
So, you could define an interface like:
public interface INamedPerson
{
int ID { get; }
string FirstName { get; }
string LastName { get; }
}
Make your entities implement this interface. Auto-generated entities are (typically) partial classes, so in your own, new code files (not in the auto-generated code files themselves), you would do something like:
public partial class Student : INamedPerson
{
public int ID
{
get
{
return StudentId;
}
}
}
and
public partial class Teacher : INamedPerson
{
public int ID
{
get
{
return TeacherId;
}
}
}
Now, you may not even need to add the ID property if you already have it. However, if the identity property in each class is different, this adapter can be one way to implement the interface you need.
Then, for the method itself, an example would be:
public List<INamedPerson> MakeListOfType(Type type)
{
if (type == typeof(Student))
{
// Get your list of students. I'll just use a made-up
// method that returns List<Student>.
return GetStudentList().Select<Student, INamedPerson>(s => (INamedPerson)s)
.ToList<INamedPerson>();
}
if (type == typeof(Teacher))
{
return GetTeacherList().Select<Teacher, INamedPerson>(t => (INamedPerson)t)
.ToList<INamedPerson>();
}
throw new ArgumentException("Invalid type.");
}
Now, there are certainly ways to refine this pattern. If you have a lot of related classes, you may want to use some sort of dependency injection framework. Also, you may notice that there is a lot of duplication of code. You could instead pass a function (like GetStudentList or GetTeacherList) by doing something like
public List<INamedPerson> GetListFromFunction<T>(Func<IEnumerable<T>> theFunction) where T : INamedPerson
{
return theFunction().Select<T, INamedPerson>(t => (INamedPerson)t).ToList<INamedPerson>();
}
Of course, using this function requires, once again, the type passed in to be known at compile time. However, at some point, you're going to have to decide on a type, so maybe that is the appropriate time. Further, you can make your life a little simpler by leaving off the generic type at method call time; as long as you are passing in a function that takes no arguments and returns an IEnumerable of objects of the same type that implement INamedPerson, the compiler can figure out what to use for the generic type T.
I have a stored procedure in my Entity Framework Model. I've added a Function Import and mapped the results to a Complex Type.
I want to add an extra property to this Complex type, that I'll populate in my Domain Service, not coming back from the stored procedure. I added a myClass.shared.cs file and implemented added the property like so:
//myClass.shared.cs
public partial class myClass
{
public string myProperty {get;set;}
}
I populate this in my domain service when I return the object, e.g.:
public myClass GetMyClass(int myClassID)
{
myClass theClass= this.ObjectContext.StoredProc(myClassID).FirstOrDefault();
class.myProperty = 12345;
return theClass;
}
When I get the return values of this method on the client side theClass.myProperty is always null but all values from the stored procedure are populated, am I missing something?
I've tried decorating the myProperty with the [DataMember] attribute but this throws the error:
"The type 'myClass' already contains a
definition for 'myProperty'"
How can I get this to return the value set in the Domain Service to the client?
There was no need to put this in the shared.cs class. The shared.cs class copies the actual code over to the client side and is useful for adding methods etc. but to add a new property, all I had to do was add a partial class (NOT in myClass.shared.cs) and decorate it with DataMember.
public partial class myClass
{
[DataMember]
public string myProperty {get;set;}
}