Pull to refresh

asp.net: полезные вещи, часть вторая

Reading time2 min
Views7.3K
Атрибуты полезная вещь, которая является одним из основных механизмов .net framework. В этой статье я предлагаю рассмотреть один простой пример использования атрибутов. Данная статья продолжает предыдущую статью и использует определенные там методы расширения.

Иногда существует потребность разом проверить некоторую валидность состояния объекта. К примеру, может потребоваться быть уверенным, что все необходимые поля и свойства объекта инициализированы и не равны null. Для решения такой задачи применимы атрибуты.

Вот простой пример объявления атрибута:
    [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, Inherited = false, AllowMultiple = false)]
    sealed public class CheckNullAttribute : Attribute
    {
        public CheckNullAttribute()
        {
        }
    }


Объявляется атрибут для полей и свойств, который не будет наследоваться, и не будет иметь возможности задаваться несколько раз. Для обработки этого атрибут требуется некоторая логика, которую я привожу ниже (здесь и применяются один из методов расширения о которых шла речь в первой статье):
    public class CheckNullMembers
    {
        public static void Check(Type p_type, object p_obj)
        {
            if (p_type == null || p_obj == null)
                throw new Exception(“Недопустимые параметры”);

            MemberInfo[] _members = p_type.FindMembers(MemberTypes.Field | MemberTypes.Property,
                BindingFlags.DeclaredOnly | BindingFlags.Static | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public,
                null, null);

            foreach (MemberInfo member in _members)
            {
                bool _isDef = Attribute.IsDefined(member, typeof(CheckNullAttribute));
                if (_isDef)
                {
                    if (member.GetValue(p_obj) == null)
                        throw new Exception(String.Format("{0} не инициализировано и равно null", member.Name));
                }
            }
        }
    }


Где это применимо? Как известно, при разработке страницы или контрола на aps.net можно объявить публичное свойство и инициализировать его в разметке, примерно так:
    public int? BranchId
    {
        get;
        set;
    }
    <uc3:BranchHint ID="BranchHint1" runat="server" BranchId=”12” />


Теперь применим для этого кода атрибут и добавим логику проверки:
    [CheckNull()]
    public int? BranchId
    {
        get;
        set;
    }
    protected void Page_Load(object sender, EventArgs e)
    {
        if (this.Visible)
        {
            CheckNullMembers.Check(this.GetType().BaseType, this);
        }
    }


В данном коде произойдет проверка BranchId на null и в случае, если BranchId не имеет значения возникнет исключение.

Комментарий: в Check передается и тип и экземпляр класса. Делается это в связи с тем, что в период выполнения тип страницы по this получить нельзя, asp.net оборачивает каждую страницу в пространство имен ASP. Все приватные поля страницы не будут видны если взять тип через this.GetType(). В связи с этим, программисту придется самому явно указать какой именно тип обрабатывать. Возможно решение не идеально, буду рад выслушать альтернативные варианты.
Tags:
Hubs:
Total votes 11: ↑7 and ↓4+3
Comments33

Articles