es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Método de extensión para obtener atributos personalizados de C#.

¿Alguien puede ayudarme a crear un método de extensión para atributos personalizados de Newtonsoft.Json y MongoDB?

Digamos que tengo la siguiente clase:

public class Foo
{
    [BsonElement("MyCustomDbName")]
    [JsonProperty("MyCustomJsonName")]
    public string Name { get; set; }
}

¿Cómo se crea un método de extensión para obtener lo siguiente?

var myFoo = new Foo(){Name=""};
var mongoDbElementName = myFoo.Name.GetMongoDbElementName(); // debería devolver 'MyCustomDbName'
var jsonPropertyName = myFoo.Name.GetJsonPropertyName(); // debería devolver 'MyCustomJsonName'

O directamente con la propia clase:

var mongoDbElementName = Foo.Name.GetMongoDbElementName(); // debería devolver 'MyCustomDbName'
var jsonPropertyName = Foo.Name.GetJsonPropertyName(); // debería devolver 'MyCustomJsonName'

He intentado cosas como esta:

public static string GetMongoDbElementName(this Type modelType, PropertyInfo property)
{
    return (modelType.GetProperty(nameof(property)) ?? throw new InvalidOperationException()).GetCustomAttribute<bsonelementattribute>()?.ElementName;
}

Pero ¿hay alguna forma de hacerlo sin parámetros?

Gracias de antemano

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Sí, es posible crear métodos de extensión para atributos personalizados en Newtonsoft.Json y MongoDB sin pasar ningún parámetro. Aquí tienes un ejemplo:

    public static class ExtensionMethods
    {
        public static string GetMongoDbElementName<t>(this Expression<><t, object="">> propertyExpression)
        {
            var propertyInfo = GetPropertyInfo(propertyExpression);
            return GetBsonElementName(propertyInfo);
        }
    
        public static string GetJsonPropertyName<t>(this Expression<><t, object="">> propertyExpression)
        {
            var propertyInfo = GetPropertyInfo(propertyExpression);
            return GetJsonPropertyName(propertyInfo);
        }
    
        private static PropertyInfo GetPropertyInfo<t>(Expression<><t, object="">> propertyExpression)
        {
            var expression = propertyExpression.Body as MemberExpression ?? ((UnaryExpression)propertyExpression.Body).Operand as MemberExpression;
            return expression?.Member as PropertyInfo ?? throw new ArgumentException("Expresión de propiedad inválida.");
        }
    
        private static string GetBsonElementName(PropertyInfo propertyInfo)
        {
            return propertyInfo.GetCustomAttribute<bsonelementattribute>()?.ElementName ?? propertyInfo.Name;
        }
    
        private static string GetJsonPropertyName(PropertyInfo propertyInfo)
        {
            return propertyInfo.GetCustomAttribute<jsonpropertyattribute>()?.PropertyName ?? propertyInfo.Name;
        }
    }
    

    En este ejemplo, utilizamos expresiones lambda para obtener la información de la propiedad sin pasar ningún parámetro. El método GetPropertyInfo extrae el objeto PropertyInfo de la expresión lambda y lanza una excepción si la expresión es inválida.

    Los métodos GetBsonElementName y GetJsonPropertyName utilizan el objeto PropertyInfo para recuperar los atributos BsonElement y JsonProperty y sus nombres respectivos.

    Para utilizar estos métodos de extensión, puedes llamarlos directamente en la propiedad, de esta manera:

    var mongoDbElementName = nameof(Foo.Name).GetMongoDbElementName();
    var jsonPropertyName = nameof(Foo.Name).GetJsonPropertyName();
    

    Alternativamente, puedes utilizar expresiones lambda para obtener el nombre de la propiedad, de esta manera:

    csharp
    var myFoo = new Foo() { Name = "" };
    var mongoDbElementName = myFoo.GetMongoDbElementName(f => f.Name);
    var jsonPropertyName = myFoo.GetJsonPropertyName(f => f.Name);
    </t,></t,></t,>

Comments are closed.