CSLA.NET快速入门系列——命令对象(CommandObject)
命令对象(CommandObject)是CSLA框架中另一类比较重要的对象,它主要用于在服务端执行一段代码,这段代码可能是简单的数据访问,也可能是复杂的工作流或其它可在服务端运行的对象。
命令对象的功能实际上也要以通过ReadOnlyBusiness对象来实现,但是使用ReadOnlyBusiness对象实现感觉复杂而不直观。而使用命令对象来实现则非常清晰而明确,即用于“运行服务器端命令“。
CSLA框架中提供了命令对象的基类:CommandBase<T>,该类提供了一个用来执行服务端代码的虚方法:
protected virtual void DataPortal_Execute()
在实现我们自己的命令对象时,需要继承CommandBase<T>基类,同时重写DataPortal_Execute方法实现真正的服务端代码。
如上面所说的,继承CommandBase<T>基类并重写DataPortal_Execute方法就已经实现了一个命令对象,不过,为了更加清晰和方便调用,CSLA命令对象一般会实现以下的编程模型:
提供一静态工厂方法(FactoryMethod)来供调用方使用本命令对象:
public static object Execute(object input,..)
该方法的输入参数可以为多个,提供实际的命令输入。
该方法的返回参数即为命令执行后的返回结果。
该方法的执行过程:
客户端代码(BeforeServer())=>服务端代码(DataPortal_Execute())=>客户端代码(AfterServer())
BeforeServer和AfterServer不是必须的,可以为空方法。
BeforeServer在服务端方法调用前做一些数据准备,同样AfterServer在服务端方法调用后做数据处理工作。
我们以CSLA中常用的ExsitsCommand举例命令对象的实现模式:
[Csla.Server.ObjectFactory(FactoryNames.ExistsCommandFactoryName)]
public class ExistsCommand : CommandBase<ExistsCommand>
{
#region Constructor(s)
private ExistsCommand()
{
}
#endregion
#region Authorization Methods
public static bool CanExecuteCommand()
{
return true;
}
#endregion
#region Synchronous Factory Methods
public static bool Execute<T>(T criteria) where T : IGeneratedCriteria
{
if (!CanExecuteCommand())
throw new System.Security.SecurityException("Not authorized to execute command");
var cmd = new ExistsCommand();
cmd.BeforeServer(criteria);
cmd = DataPortal.Execute(cmd);
cmd.AfterServer();
return cmd.Result;
}
#endregion
#region Client-side Code
internal IGeneratedCriteria Criteria { get; set; }
public bool Result { get; internal set; }
private void BeforeServer(IGeneratedCriteria criteria)
{
Criteria = criteria;
Result = false;
}
private void AfterServer()
{
}
#endregion
}
在Client-side Code区域定义了:
输入参数:internal IGeneratedCriteria Criteria { get; set; }
输出参数:public bool Result { get; internal set; }
BeforeServer方法:private void BeforeServer(IGeneratedCriteria criteria)
AfterServer方法: private void AfterServer()
静态工厂方法实现则非常清晰简单:
public static bool Execute<T>(T criteria) where T : IGeneratedCriteria
        {
            if (!CanExecuteCommand())
                throw new System.Security.SecurityException("Not authorized to execute command");
            var cmd = new ExistsCommand();
            cmd.BeforeServer(criteria);
            cmd = DataPortal.Execute(cmd);
            cmd.AfterServer();
            return cmd.Result;
        }
本例由于采用FactoryObject模式,服务端方法没有直接在命令对象中实现,而是在相应的ObjectFactory类(由命令对象的ObjectFactoryAttribute中指定)中实现,代码发下:
public ExistsCommand Execute(ExistsCommand item)
{
string commandText = string.Format("SELECT COUNT(1) FROM {0} {1}", item.Criteria.TableFullName, ADOHelper.BuildWhereStatement(item.Criteria.StateBag));
using (DbConnection connection = ADOHelper.CreateConnection())
{
connection.Open();
using (DbCommand command = ADOHelper.CreateCommand(connection,commandText))
{
command.Parameters.AddRange(ADOHelper.DbParameters(item.Criteria.StateBag));
item.Result = Convert.ToInt32(command.ExecuteScalar()) > 0;
}
}
return item;
}
#endregion
通过上面的模式实现命令对象,调用方(UI或者其它对象)调用命令对象非常简单:
MyCriteria criteria;
// criteria = new MyCriteria();
bool result = ExistsCommand.Execute(criteria);
 
                    
                 
 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号