impostazione automatica dei membri della classe come la classe operativa dei server Photon

0

Sto cercando di imitare qualcosa che ho visto su Photon Server con la mia applicazione. Entity Framework fa qualcosa di simile. Photon Server ha una classe operativa. Si passa a un dizionario di <byte,object> e si riempie automaticamente i membri della classe e fa anche alcune annotazioni di dati. Ad esempio

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

Ora in questo, la richiesta contiene un Dictionary<byte,object> il byte è ciò a cui l'annotazione Data si riferisce come il Codice in qualche modo richiede che il dizionario cerchi la chiave che corrisponde a quale codice è impostato e assegna Messaggio al valore della chiave .

Ho bisogno di fare la stessa cosa e non ho avuto fortuna a trovare qualcosa su google (anche se non sono sicuro di cosa si chiami) So che la riga [DataMember] è un'annotazione dati personalizzata e quelli che capisco è la parte di prendere il codice nell'annotazione dati e l'assegnazione del valore al campo sottostante.

Quello che so delle annotazioni dei dati personalizzati sta usando la convalida con loro (che questa classe fa anche in Photon tramite MyCustomOperation.IsValid anche se questa parte lo posso immaginare penso).

    
posta Michael Loriault 28.10.2014 - 09:14
fonte

1 risposta

1

Ok, finalmente l'ho capito senza usare il riflesso

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
    
risposta data 28.10.2014 - 23:06
fonte

Leggi altre domande sui tag