CSLA框架的codesmith模板改造

一直有关注CSLA框架,最近闲来无事,折腾了下,在最新的r3054版本基础上修改了一些东西,以备自己用,有兴趣的园友可以下载共同研究

1、添加了默认的授权规则

如果是列表对象则生成列表权限,User的只读列表和可编辑列表生成的都是User.List权限,admin角色具有所有权限:
public partial class UserInfoList
    {
        #region Authorization Rules

        /// <summary>
        /// Allows the specification of CSLA based authorization rules for a collection list.  Specifies what roles can 
        /// perform which operations for a given business object
        /// </summary>
        public static void AddObjectAuthorizationRules()
        {
            Csla.Rules.BusinessRules.AddRule(typeof(UserInfoList), new Csla.Rules.CommonRules.IsInRole(Csla.Rules.AuthorizationActions.GetObject, "admin","User.List"));
        }
        #endregion
    }
public partial class UserList
    {
        #region Authorization Rules

        /// <summary>
        /// Allows the specification of CSLA based authorization rules for a collection list.  Specifies what roles can 
        /// perform which operations for a given business object
        /// </summary>
        public static void AddObjectAuthorizationRules()
        {
            Csla.Rules.BusinessRules.AddRule(typeof(UserList), new Csla.Rules.CommonRules.IsInRole(Csla.Rules.AuthorizationActions.GetObject, "admin","User.List"));
        }
        #endregion
    }
如果是可编辑的跟对象则生成增删改读权限,admin角色具有所有权限:
public partial class User
    {
        #region Authorization Rules

        /// <summary>
        /// Allows the specification of CSLA based authorization rules.  Specifies what roles can 
        /// perform which operations for a given business object
        /// </summary>
        public static void AddObjectAuthorizationRules()
        {
            Csla.Rules.BusinessRules.AddRule(typeof(User), new Csla.Rules.CommonRules.IsInRole(Csla.Rules.AuthorizationActions.GetObject, "admin","User.Get"));
            Csla.Rules.BusinessRules.AddRule(typeof(User), new Csla.Rules.CommonRules.IsInRole(Csla.Rules.AuthorizationActions.CreateObject, "admin","User.Create"));
            Csla.Rules.BusinessRules.AddRule(typeof(User), new Csla.Rules.CommonRules.IsInRole(Csla.Rules.AuthorizationActions.EditObject, "admin","User.Edit"));
            Csla.Rules.BusinessRules.AddRule(typeof(User), new Csla.Rules.CommonRules.IsInRole(Csla.Rules.AuthorizationActions.DeleteObject, "admin", "User.Delete"));
        }
        #endregion
    }

2、生成权限列表的sql脚本

对应生成的权限脚本:
insert into S_Permision(Name) values('User.List');
insert into S_Permision(Name) values('User.Get');
insert into S_Permision(Name) values('User.Create');
insert into S_Permision(Name) values('User.Edit');
insert into S_Permision(Name) values('User.Delete');

3、添加了查询支持

criteria本来的查询是每个字段都是取相等的值,改造后,cirteria中每个对应的字段都增加了一个字段名+Operator的属性。Operator的值即可根据用户选择 like ,not like ,> , < ,<>

var form = ASPxNavBar1.Groups[0].FindControl("ASPxFormLayout1") as ASPxFormLayout;
                var criteria = new Business.UserCriteria();
                Csla.Data.DataMapper.Map(FormHelper.GetFormData(form), criteria);
                return criteria;
public class FormHelper
    {
        public static Dictionary<string, object> GetFormData(DevExpress.Web.ASPxFormLayout.ASPxFormLayout form)
        {
            var dict = new Dictionary<string, object>();
            foreach (DevExpress.Web.ASPxFormLayout.LayoutItem item in form.Items)
            {
                if (string.IsNullOrEmpty(item.FieldName)) continue;
                if (dict.ContainsKey(item.FieldName))
                    throw new Exception("布局中存在重复的字段");
                var value = form.GetNestedControlValueByFieldName(item.FieldName);
                if (value != null)
                    dict.Add(item.FieldName, value);
            }
            return dict;
        }
    }

4、添加了批量删除

没有加到模板中,直接复制即可使用,但是用到了criteria中新加的属性

[Serializable]
    public class MultyDeleteCommand<T, C> : CommandBase<MultyDeleteCommand<T, C>>
        where T : BusinessBase<T>
        where C : IGeneratedCriteria, new()
    {
        #region Authorization Methods

        public static bool CanExecuteCommand()
        {
            return Csla.Rules.BusinessRules.HasPermission(Csla.Rules.AuthorizationActions.DeleteObject,
                 typeof(T));
        }

        #endregion

        #region Factory Methods

        public static bool Execute(IEnumerable<object> pkList)
        {
            if (!CanExecuteCommand())
                throw new System.Security.SecurityException("没有权限执行删除操作");

            MultyDeleteCommand<T, C> cmd = new MultyDeleteCommand<T, C>();
            cmd.PKList = pkList;
            cmd.BeforeServer();
            cmd = DataPortal.Execute<MultyDeleteCommand<T, C>>(cmd);
            cmd.AfterServer();
            return cmd.Result;
        }

        private MultyDeleteCommand()
        { /* require use of factory methods */ }

        #endregion

        #region Client-side Code


        public static readonly PropertyInfo<bool> ResultProperty = RegisterProperty<bool>(p => p.Result);
        public bool Result
        {
            get { return ReadProperty(ResultProperty); }
            set { LoadProperty(ResultProperty, value); }
        }

        public IEnumerable<object> PKList { get; set; }

        private void BeforeServer()
        {
            // TODO: implement code to run on client
            // before server is called
        }

        private void AfterServer()
        {
            // TODO: implement code to run on client
            // after server is called
        }

        #endregion

        #region Server-side Code

        protected override void DataPortal_Execute()
        {
            string temp = ""; string key = "";
            var criteria = new C();
            if (string.IsNullOrWhiteSpace(criteria.TableFullName) || string.IsNullOrWhiteSpace(criteria.PKName))
                throw new Exception("表名和主键名不能为空");

            SqlParameter[] parm = new SqlParameter[PKList.Count()]; //初始化参数个数
            for (int i = 0; i < PKList.Count(); i++)
            {
                key = "@StringId" + i.ToString();
                temp += key + ","; //将每个参数连接起来
                parm[i] = new SqlParameter(key, PKList.ElementAt(i));
            }
            temp = (temp + ")").Replace(",)", ""); //去掉最后一个逗号          

            string commandText = string.Format("DELETE {0} WHERE [{1}] IN ({2})",criteria.TableFullName, criteria.PKName, temp);
            if (!string.IsNullOrEmpty(criteria.SoftDeletedName))
                commandText = string.Format("UPDATE {0} SET [{1}]=1 WHERE [{2}] IN ({3})", criteria.TableFullName, criteria.SoftDeletedName, criteria.PKName, temp);

            using (var connection = new SqlConnection(ADOHelper.ConnectionString))
            {
                connection.Open();
                using (var command = new SqlCommand(commandText, connection))
                {
                    command.Parameters.AddRange(parm);

                    //result: The number of rows changed, inserted, or deleted. -1 for select statements; 0 if no rows were affected, or the statement failed. 
                    int result = command.ExecuteNonQuery();
                    if (result == 0)
                        throw new DBConcurrencyException("您提交的数据已过期,请刷新您的界面后重试.");
                    else
                        Result = true;
                }
            }

        }

        #endregion
    }
View Code

5、添加了软删除的功能

当数据表中有一列名为bit类型的DeleteFlag(默认值为0,not null)时,自动启用软删除,即执行对象的删除操作时并不是从数据库中删除对象,而是设置DeleteFlag字段为1,使用criteria条件查询时,除非指定显式设置DeletedFlag属性值,否则默认按照DeleteFlag<>1查询,即已经删除的记录不会查出来,就像真的被从数据库中删除了一样。

如果要修改数据库中的列名,修改模板Common\AutoColunmConfig.cst中的DeletedFlag属性即可

6、添加了添加修改时间,创建者修改者的自动处理

  数据库表中存在CreateAt,UpdateAt,CreateUserID,UpdateUserID时自动生成代码,在Common\AutoColunmConfig.cst模板中可以配置对应的数据库字段和读取当前用户ID的代码。UserIDAccessor配置生成当前用户ID的代码。
 <%@ Property Name="DeletedFlag" Default="DeletedFlag" Type="System.String" %>
<%@ Property Name="Create_At" Default="CreateAt" Type="System.String" %>
<%@ Property Name="Update_At" Default="UpdateAt" Type="System.String" %>
<%@ Property Name="Create_UserID" Default="CreateUserID" Type="System.String" %>
<%@ Property Name="Update_UserID" Default="UpdateUserID" Type="System.String" %>
<%@ Property Name="UserIDAccessor" Default="Csla.ApplicationContext.User == null ? (int?)null : (Csla.ApplicationContext.User.Identity as MFKIdentity).UserID" Type="System.String" %>
 

7、添加了禁止删除系统预设字段的业务规则(不在模板中,复制代码在需要的地方调用即可)

 1  public class DenyDeleteSystemDefinedObject<T> : Csla.Rules.CommonRules.IsInRole
 2         where T : Csla.BusinessBase<T>
 3     {
 4         Func<T, bool> isSystemDefined;
 5         public DenyDeleteSystemDefinedObject(Func<T, bool> _isSystemDefined, params string[] roles)
 6             : base(Csla.Rules.AuthorizationActions.DeleteObject, roles)
 7         {
 8             isSystemDefined = _isSystemDefined;
 9         }
10 
11         protected override void Execute(Csla.Rules.AuthorizationContext context)
12         {
13             base.Execute(context);
14             if (!context.HasPermission) return;
15 
16             if (context.Target != null && context.Target is T && isSystemDefined(context.Target as T))
17             {
18                 context.HasPermission = false;
19                 throw new System.InvalidOperationException(Properties.Resources.SystemDefinedObjectCannotDelete);
20             }
21         }
22     }

  使用方式,例如:有一个系统设置的根对象Setting:

 1 public partial class Setting: BusinessBase<Setting>
 2     {
 3         static Dictionary<int, string> _systemDefinedList = null;
 4         /// <summary>
 5         /// 系统预设值
 6         /// </summary>
 7         public static Dictionary<int, string> SystemDefined
 8         {
 9             get
10             {
11                 if (_systemDefinedList == null)
12                 {
13                     _systemDefinedList = new Dictionary<int, string>();
14                     _systemDefinedList.Add(1, "站点名称");
15                     _systemDefinedList.Add(2, "LOGO图片");
16                 }
17                 return _systemDefinedList;
18             }
19         }
20 
21         public bool IsSystemDefined
22         {
23             get
24             {
25                 return Setting.SystemDefined.ContainsValue(KeyName) || Setting.SystemDefined.ContainsKey(Identification);
26             }
27         }
28 
29     #region Authorization Rules
30 
31         /// <summary>
32         /// Allows the specification of CSLA based authorization rules.  Specifies what roles can 
33         /// perform which operations for a given business object
34         /// </summary>
35         public static void AddObjectAuthorizationRules()
36         {
37             Csla.Rules.BusinessRules.AddRule(typeof(Setting), new Csla.Rules.CommonRules.IsInRole(Csla.Rules.AuthorizationActions.GetObject, "admin", "Setting.Get"));
38             Csla.Rules.BusinessRules.AddRule(typeof(Setting), new Csla.Rules.CommonRules.IsInRole(Csla.Rules.AuthorizationActions.CreateObject, "admin", "Setting.Create"));
39             Csla.Rules.BusinessRules.AddRule(typeof(Setting), new Csla.Rules.CommonRules.IsInRole(Csla.Rules.AuthorizationActions.EditObject, "admin", "Setting.Edit"));
40             Csla.Rules.BusinessRules.AddRule(typeof(Setting), new DenyDeleteSystemDefinedObject<Setting>(
41                 s => s.IsSystemDefined, "admin", "Setting.Delete"));
42         }
43         #endregion
44 
45 
46         partial void OnDeleting(SettingCriteria criteria, ref bool cancel)
47         {
48             if (Setting.SystemDefined.ContainsValue(criteria.KeyName)
49                            || Setting.SystemDefined.ContainsKey(criteria.Identification))
50             {
51                 throw new System.InvalidOperationException(Properties.Resources.SystemDefinedObjectCannotDelete);
52             }
53         }
54     }

  

注意事项:

1、表名不能以Info结尾
2、字段名不可以和Csla的业务对象的同名,例如: 字段名不能为Parent,IsDeleted 等

 

附:可能由于CSLA对使用者的要求相对其他框架较高,目前国内CSLA的学习社区太少,这么优秀的框架,居然国内都不火,真是可惜了,我建了个交流群,欢迎感兴趣的朋友一起来学习。

CSLA&DevExpress交流群: 367088648

 
 
 
原文地址:https://www.cnblogs.com/huolong/p/3710443.html