0

I'm wanting to mimic something that I saw in Photon Server with my application. Entity Framework does something similar. Photon Server has an Operation class. You pass it a dictionary of <byte,object> and it auto fills the class members and also does some data annotation. For example

public class MyCustomOperation : Operation
{
 public MyCustomOperation(IRpcProtocol protocol, OperationRequest request) : base(protocol, request)
 {
 }
 [DataMember(Code = 100, IsOptional = false)]
 public string Message { get; set; }
}

Now in this, request contains a Dictionary<byte,object> the byte is what the Data annotation refers to as the Code it somehow takes that dictionary looks up the key that matches what code is set to and assigns Message to the value of the key.

I need to do the same thing and have had no luck finding anything on google (although not sure what this is called) I know the [DataMember] line is a custom data annotation and those I do understand its the part of taking the code in the data annotation and assigning the value to the field under it.

What I know about custom data annotations is using validation with them (which this class also does in Photon via a MyCustomOperation.IsValid although this part I can figure out I think).

asked Oct 28, 2014 at 8:14

1 Answer 1

1

Ok I finally figured this out without using reflection as well

DataMemberAttribute class:

[AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]
public class DataMemberAttribute : Attribute
{
 public byte Code { get; set; }
 public bool IsOptional { get; set; }
 public string ErrorMessage { get; set; }
}

Operation Class:

public class Operation
{
 private readonly List<string> _errorMessages; 
 protected Operation(Dictionary<byte,object> parameters)
 {
 _errorMessages = new List<string>();
 foreach (var prop in GetType().GetProperties())
 {
 var da = prop.GetCustomAttributes(typeof(DataMemberAttribute), false) as DataMemberAttribute[];
 if (!(da == null || da.Length <= 0))
 {
 if (parameters.ContainsKey(da[0].Code))
 {
 prop.SetValue(this, Convert.ChangeType(parameters[da[0].Code], prop.PropertyType), null);
 }
 else
 {
 _errorMessages.Add(!string.IsNullOrEmpty(da[0].ErrorMessage) ? da[0].ErrorMessage : string.Format("{0} is Required", prop.Name));
 }
 }
 }
 }
 public bool IsValid
 {
 get {
 return _errorMessages.Count <= 0;
 }
 }
 public List<string> ErrorMessages
 {
 get { return _errorMessages; }
 } 
}

Sample Derived class:

public class Operation2 : Operation
{
 public Operation2(Dictionary<byte,object> parameters) : base(parameters)
 {}
 [DataMember(Code = 1, IsOptional = false, ErrorMessage="Username is Required")]
 public string Username { get; set; }
 [DataMember(Code = 2, IsOptional = false, ErrorMessage="Password is Required"))]
 public string Password { get; set; }
 [DataMember(Code = 3, IsOptional = false, ErrorMessage="Email is Required"))]
 public string Email { get; set; } 
}

Test Program:

class Program
{
 static void Main()
 {
 var paramters = new Dictionary<byte, object> {{1, "someuser"}, {2, "password"}, {3, "[email protected]"}};
 var operation = new Operation2(paramters);
 var paramters2 = new Dictionary<byte, object> { { 1, "someuser" }, { 10, "password" }, { 3, "[email protected]" } };
 var operation2 = new Operation2(paramters2);
 Console.WriteLine("Operation 1 Contains:");
 Console.WriteLine("Username {0}", operation.Username);
 Console.WriteLine("Email {0}", operation.Email);
 Console.WriteLine("Password {0}", operation.Password);
 Console.WriteLine("operation 1 {0}", operation.IsValid);
 Console.WriteLine();
 Console.WriteLine("Operation 2 Contains:");
 Console.WriteLine("Username {0}", operation2.Username);
 Console.WriteLine("Email {0}", operation2.Email);
 Console.WriteLine("Password {0}", operation2.Password);
 Console.WriteLine("operation 2 {0}", operation2.IsValid);
 Console.ReadLine();
 }
}

Produces the following output:

Operation 1 Contains:
Username someuser
Email [email protected]
Password password
operation 1 True
Operation 2 Contains:
Username someuser
Email [email protected]
Password
operation 2 False
answered Oct 28, 2014 at 22:06

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.