⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 brokenrules.cs

📁 C# 版本的一个三层商业架构
💻 CS
📖 第 1 页 / 共 2 页
字号:
using System;
using System.Collections;
using System.Collections.Specialized;
using CSLA.Resources;

namespace CSLA
{
  /// <summary>
  /// Tracks the business rules broken within a business object.
  /// </summary>
  [Serializable()]
  public class BrokenRules
  {
    #region Rule structure

    /// <summary>
    /// Stores details about a specific broken business rule.
    /// </summary>
    [Serializable()]
      public struct Rule
    {
      string _name;
      string _description;
      string _property;

      internal Rule(string name, string description)
      {
        _name = name;
        _description = description;
        _property = string.Empty;
      }

      internal Rule(string name, string description, string property)
      {
        _name = name;
        _description = description;
        _property = property;
      }

      /// <summary>
      /// Provides access to the name of the broken rule.
      /// </summary>
      /// <remarks>
      /// This value is actually readonly, not readwrite. Any new
      /// value set into this property is ignored. The property is only
      /// readwrite because that is required to support data binding
      /// within Web Forms.
      /// </remarks>
      /// <value>The name of the rule.</value>
      public string Name
      {
        get
        {
          return _name;
        }
        set
        {
          // the property must be read-write for Web Forms data binding
          // to work, but we really don't want to allow the value to be
          // changed dynamically so we ignore any attempt to set it
        }
      }

      /// <summary>
      /// Provides access to the description of the broken rule.
      /// </summary>
      /// <remarks>
      /// This value is actually readonly, not readwrite. Any new
      /// value set into this property is ignored. The property is only
      /// readwrite because that is required to support data binding
      /// within Web Forms.
      /// </remarks>
      /// <value>The description of the rule.</value>
      public string Description
      {
        get
        {
          return _description;
        }
        set
        {
          // the property must be read-write for Web Forms data binding
          // to work, but we really don't want to allow the value to be
          // changed dynamically so we ignore any attempt to set it
        }
      }

      /// <summary>
      /// Provides access to the property affected by the broken rule.
      /// </summary>
      /// <remarks>
      /// This value is actually readonly, not readwrite. Any new
      /// value set into this property is ignored. The property is only
      /// readwrite because that is required to support data binding
      /// within Web Forms.
      /// </remarks>
      /// <value>The property affected by the rule.</value>
      public string Property
      {
        get
        {
          return _property;
        }
        set
        {
          // the property must be read-write for Web Forms data binding
          // to work, but we really don't want to allow the value to be
          // changed dynamically so we ignore any attempt to set it
        }
      }
    }

    #endregion

    #region RulesCollection

    /// <summary>
    /// A collection of currently broken rules.
    /// </summary>
    /// <remarks>
    /// This collection is readonly and can be safely made available
    /// to code outside the business object such as the UI. This allows
    /// external code, such as a UI, to display the list of broken rules
    /// to the user.
    /// </remarks>
    [Serializable()]
      public class RulesCollection : CSLA.Core.BindableCollectionBase
    {
      bool _validToEdit = false;

      /// <summary>
      /// Returns a <see cref="T:CSLA.BrokenRules.Rule" /> object
      /// containing details about a specific broken business rule.
      /// </summary>
      /// <param name="Index"></param>
      /// <returns></returns>
      public Rule this [int index]
      {
        get 
        { 
          return (Rule)List[index]; 
        }
      }

      /// <summary>
      /// Returns the first <see cref="T:CSLA.BrokenRules.Rule" /> object
      /// corresponding to the specified property.
      /// </summary>
      /// <remarks>
      /// <para>
      /// When a rule is marked as broken, the business developer can provide
      /// an optional Property parameter. This parameter is the name of the
      /// Property on the object that is most affected by the rule. Data binding
      /// may later use the IDataErrorInfo interface to query the object for
      /// details about errors corresponding to specific properties, and this
      /// value will be returned as a result of that query.
      /// </para><para>
      /// Code in a business object or UI can also use this value to retrieve
      /// the first broken rule in <see cref="T:CSLA.BrokenRules" /> that corresponds
      /// to a specfic Property on the object.
      /// </para>
      /// </remarks>
      /// <param name="Property">The name of the property affected by the rule.</param>
      public Rule RuleForProperty(string property)
      {
        foreach(Rule item in List)
          if(item.Property == property)
            return item;
        return new Rule();
      }

      internal RulesCollection()
      {
        AllowEdit = false;
        AllowRemove = false;
        AllowNew = false;
      }

      internal void Add(string name, string description)
      {
        Remove(name);
        _validToEdit = true;
        List.Add(new Rule(name, description));
        _validToEdit = false;
      }

      internal void Add(string name, string description, string property)
      {
        Remove(name);
        _validToEdit = true;
        List.Add(new Rule(name, description, property));
        _validToEdit = false;
      }

      internal void Remove(string name)
      {
        // we loop through using a numeric counter because
        // the base class Remove requires a numeric index
        _validToEdit = true;
        for(int index = 0; index < List.Count; index++)
          if(((Rule)List[index]).Name == name)
          {
            List.Remove(List[index]);
            break;
          }
        _validToEdit = false;
      }

      internal bool Contains(string name)
      {
        for(int index = 0; index < List.Count; index++)
          if(((Rule)List[index]).Name == name)
            return true;
        return false;
      }

      protected override void OnClear()
      {
        if(!_validToEdit)
          throw new NotSupportedException(Strings.GetResourceString("ClearInvalidException"));
      }

      protected override void OnInsert(int index, object val)
      {
        if(!_validToEdit)
          throw new NotSupportedException(Strings.GetResourceString("InsertInvalidException"));
      }

      protected override void OnRemove(int index, object val)
      {
        if(!_validToEdit)
          throw new NotSupportedException(Strings.GetResourceString("RemoveInvalidException"));
      }

      protected override void OnSet(int index, object oldValue, object newValue)
      {
        if(!_validToEdit)
          throw new NotSupportedException(
            Strings.GetResourceString("ChangeInvalidException"));
      }
    }

    #endregion

    private RulesCollection _brokenRules = new RulesCollection();
    [NonSerialized()]
    [NotUndoable()]
    private object _target;

    #region Rule Manager

    /// <summary>
    /// Sets the target object so the Rules Manager functionality
    /// has a reference to the object containing the data to
    /// be validated.
    /// </summary>
    /// <remarks>
    /// The object here is typically your business object. In your
    /// business class you'll implement a method to set up your
    /// business rules. As you do so, you need to call this method
    /// to give BrokenRules a reference to your business object
    /// so it has access to your object's data.
    /// </remarks>
    /// <param name="target">A reference to the object containing
    /// the data to be validated.</param>
    public void SetTargetObject(object target)
    {
      _target = target;
    }

    #region RuleHandler delegate

    /// <summary>
    /// Delegate that defines the method signature for all rule handler methods.
    /// </summary>
    /// <remarks>
    /// <para>
    /// When implementing a rule handler, you must conform to the method signature
    /// defined by this delegate. You should also apply the Description attribute
    /// to your method to provide a meaningful description for your rule.
    /// </para><para>
    /// The method implementing the rule must return True if the data is valid and
    /// return False if the data is invalid.
    /// </para>
    /// </remarks>
    public delegate bool RuleHandler(object target, RuleArgs e);

    #endregion

    #region RuleArgs class

    /// <summary>
    /// Object providing extra information to methods that
    /// implement business rules.
    /// </summary>
    public class RuleArgs
    {
      private string _propertyName;
      private string _description;

      /// <summary>
      /// The (optional) name of the property to be validated.
      /// </summary>
      public string PropertyName
      {
        get
        {
          return _propertyName;
        }
      }

      /// <summary>
      /// Set by the rule handler method to describe the broken
      /// rule.
      /// </summary>
      /// <remarks>
      /// <para>
      /// If the rule handler sets this property, this value will override
      /// any description attribute value associated with the rule handler
      /// method.
      /// </para><para>
      /// The description string returned via this property 
      /// is provided to the UI or other consumer
      /// about which rules are broken. These descriptions are intended
      /// for end-user display.
      /// </para><para>
      /// The description value is a .NET format string, and it can include
      /// the following tokens in addition to literal text:
      /// </para><para>
      /// {0} - the RuleName value
      /// </para><para>
      /// {1} - the PropertyName value
      /// </para><para>
      /// {2} - the full type name of the target object
      /// </para><para>
      /// {3} - the ToString value of the target object
      /// </para><para>
      /// You can use these tokens in your description string and the
      /// appropriate values will be substituted for the tokens at
      /// runtime.
      /// </para>
      /// </remarks>
      public string Description
      {
        get
        {
          return _description;
        }
        set
        {
          _description = value;
        }
      }

      /// <summary>
      /// Creates an instance of RuleArgs.
      /// </summary>
      public RuleArgs()
      {
      }

      /// <summary>
      /// Creates an instance of RuleArgs.
      /// </summary>
      /// <param name="propertyName">The name of the property to be validated.</param>
      public RuleArgs(string propertyName)
      {
        _propertyName = propertyName;
      }

      #region Empty

      private static RuleArgs _emptyArgs = new RuleArgs();

      /// <summary>
      /// Returns an empty RuleArgs object.
      /// </summary>
      public static RuleArgs Empty
      {
        get
        {
          return _emptyArgs;
        }
      }

      #endregion

    }

    #endregion

    #region Description attribute

    /// <summary>
    /// Defines the description of a business rule.
    /// </summary>
    /// <remarks>
    /// <para>
    /// The description in this attribute is used by BusinessRules
    /// as information that is provided to the UI or other consumer
    /// about which rules are broken. These descriptions are intended
    /// for end-user display.
    /// </para><para>
    /// The description value is a .NET format string, and it can include
    /// the following tokens in addition to literal text:
    /// </para><para>
    /// {0} - the RuleName value
    /// </para><para>
    /// {1} - the PropertyName value
    /// </para><para>
    /// {2} - the full type name of the target object
    /// </para><para>
    /// {3} - the ToString value of the target object
    /// </para><para>
    /// You can use these tokens in your description string and the
    /// appropriate values will be substituted for the tokens at
    /// runtime.
    /// </para><para>
    /// Instead of using this attribute, a rule handler method can
    /// set the Description property of the RuleArgs parameter to
    /// a description string. That approach can provide a more dynamic
    /// way to generate descriptions of broken rules.
    /// </para>
    /// </remarks>
    [AttributeUsage(AttributeTargets.Method)]
      public class DescriptionAttribute : Attribute
    {

      private string _text = string.Empty;

      /// <summary>
      /// Initializes the attribute with a description.
      /// </summary>
      public DescriptionAttribute(string description)
      {
        _text = description;
      }

      /// <summary>
      /// Returns the description value of the attribute.
      /// </summary>
      public override string ToString()
      {
        return _text;
      }

    }

    #endregion

    #region RuleMethod Class

    /// <summary>
    /// Tracks all information for a rule.
    /// </summary>
    private class RuleMethod
    {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -