在Orchard中为命令行工具(Command-Line)添加一个新命令

在Orchard中有一个非常好用的命令行工具(Command-Line),我们可通过运行一些命令执行多种操作,如:创建代码模板,打包模块,启用功能等等。关于命令行工具的更多介绍,可以查看《 Orchard中的命令行工具》。如何才能定义我们自己特有的命令,下面我们还是用以前所开发的 产品示例模块来举例说明。
 

首先,我们按照Orchard中的一些约定和规范在MyCompany.Products项目中添加一个Commands目录,并在此目录中添加一个ProductCommands.cs文件。例如,我们希望能够在命令行工具中添加我们要用到产品分类,并能通过相应命令快速创建产品,我们就可以通过输入以下代码实现。

 

 

ProductCommands.cs
using  System;
using  System.Linq;
using  System.Text.RegularExpressions;
using  System.Xml.Linq;
using  Orchard.Commands;
using  Orchard.ContentManagement;
using  Orchard.ContentManagement.Aspects;
using  Orchard.Core.Common.Models;
using  Orchard.Core.Navigation.Models;
using  Orchard.Core.Routable.Models;
using  Orchard.Core.Routable.Services;
using  Orchard.Security;
using  MyCompany.Products.Services;
using  Orchard.Core.Navigation.Services;
using  Orchard.Settings;
using  Orchard.Data;
using  MyCompany.Products.Models;
using  Orchard;

namespace  MyCompany.Products.Commands
{
    
///   <summary>
    
///  定义命令行功能,默认需要继承DefaultOrchardCommandHandler类
    
///   </summary>
     public   class  ProductCommands : DefaultOrchardCommandHandler 
    {
        
private   readonly  IContentManager _contentManager;
        
private   readonly  IRepository < CategoryPartRecord >  _categoryRepository;

        
public  ProductCommands(IContentManager contentManager, IRepository < CategoryPartRecord >  categoryRepository)
        {
            _contentManager 
=  contentManager;
            _categoryRepository 
=  categoryRepository;
        }

        
///   <summary>
        
///  加上OrchardSwitch属性表示改字段可以通过命令行参数来获取值
        
///   </summary>
        [OrchardSwitch]
        
public   string  Slug {  get set ; }

        [OrchardSwitch]
        
public   string  Title {  get set ; }

        [OrchardSwitch]
        
public   string  Price {  get set ; }

        [OrchardSwitch]
        
public   string  Brand {  get set ; }

        [OrchardSwitch]
        
public   string  CategoryName {  get set ; }

        [OrchardSwitch]
        
public   string  Description {  get set ; }



        
///   <summary>
        
///  在方法上加上
        
///  CommandName,定义命令名
        
///  CommandHelp,定义命令帮助
        
///   </summary>
        
///   <param name="categoryName"> 以空格为分隔依次接收此命名后的多个参数,当需要传递有空格的值可以加上引号 </param>
        
///   <returns></returns>
        [CommandName( " product category create " )]
        [CommandHelp(
" product category create <category-name>\r\n\t "   +   " Creates a new product category " )]
        
public   string  CreateCategory( string  categoryName) 
        {
            
if  (String.IsNullOrEmpty(categoryName))
            {
                
throw   new  OrchardException(T( " Your must enter a categoryname. " ));
            }

            _categoryRepository.Create(
new  CategoryPartRecord { CategoryName  =  categoryName });

            
return   " Product category created successfully! " ;
        }
        
        
///   <summary>
        
///  在方法上加上
        
///  OrchardSwitches表示当前命名所要使用的交换参数
        
///   </summary>
        
///   <returns></returns>
        [CommandName( " product create " )]
        [CommandHelp(
" product create /Slug:<slug> /Title:<title> /Price:<price> /Brand:<brand> /CategoryName:<categoryName> [/Description:<description>]\r\n\t "   +   " Creates a new product " )]
        [OrchardSwitches(
" Slug,Title,Price,Brand,CategoryName,Description " )]
        
public   string  CreateProduct()
        {
            
if  ( ! IsSlugValid(Slug))
            {
                
throw   new  OrchardException(T( " Invalid Slug provided. Product creation failed. " ));
            }

            
double  price  =   0 ;
            
if  ( ! double .TryParse( this .Price,  out  price))
            {
                
throw   new  OrchardException(T( " Invalid Price provided. Product creation failed. " ));
            }

            CategoryPartRecord category 
=  _categoryRepository.Get(x  =>  x.CategoryName  ==  CategoryName);
            
if  (category  ==   null )
            {
                
throw   new  OrchardException(T( " Invalid CategoryName provided. Product creation failed. " ));
            }

            
// 一个产品类型是由一个Route+Body+ProudctPart构成的
            var product  =  _contentManager.New( " Product " );
            product.As
< RoutePart > ().Slug  =  Slug;
            product.As
< RoutePart > ().Path  =  Slug;
            product.As
< RoutePart > ().Title  =  Title;
            product.As
< RoutePart > ().PromoteToHomePage  =   false ;
            product.As
< BodyPart > ().Text  =   this .Description;
            product.As
< ProductPart > ().Brand  =   this .Brand;
            product.As
< ProductPart > ().Price  =  price;
            product.As
< ProductPart > ().Category  =  category;

            _contentManager.Create(product);

            
return   " Product created successfully! " ;
        }

        
///   <summary>
        
///  校验Route的简短友好值
        
///   </summary>
        
///   <param name="slug"></param>
        
///   <returns></returns>
         private   static   bool  IsSlugValid( string  slug)
        {
            
//  see  http://tools.ietf.org/html/rfc3987  for prohibited chars
             return  slug  ==   null   ||  String.IsNullOrEmpty(slug.Trim())  ||  Regex.IsMatch(slug,  @" ^[^/:?#\[\]@!$&'()*+,;=\s]+$ " );
        }

    }

 

 

从上述代码中可以看出,为了能让Orchard命令行工具找到我们定义的命令,需要将ProductCommands继承于DefaultOrchardCommandHandler类。然后再执行相应命令的方法上加上CommandName属性来定义命令的名称,加上CommandHelp就可以定义命令的帮助。同时对于接收简单的命令参数时,我们可以直接在方法中添加参数。Orchard命令行工具会自动将相应命令后的字符串以空格为分隔分别给各个参数赋值。对于参数较多的情况下,我们可以在ProductCommands用定义定义多个加上OrchardSwitch的属性来接收值,定在相应的执行方法上加上OrchardSwitches属性定义该方法所用到的属性即可。

 

完成上述代码编写并编译项目后,我们就可以在Orchard命令行工具中输入:

在Orchard中为命令行工具(Command-Line)添加一个新命令  

Tips:对于输入的参数值有包含空格时,可以用引号包含参数值。如:/Title:”Office 2010”。

 

关于Orchard命令行工具的实现原理,可以查看Orchard.Commands命名空间下的相关类。Orchard.exe对应的项目为Orchard解决方案的Tools目录下的Orchard项目。等以后对这部分代码有深入学习和了解后再讲述Orchard命令行工具的实现原理吧。


代码下载点这里(解压安装nupkg)

 

你可能感兴趣的:(command)