代码改变世界

SmartClient中Web服务接口设计(二)

2007-06-22 11:11  老羽  阅读(783)  评论(1编辑  收藏  举报

   上篇讲到一种不太合适的WebService接口设计方法,主要原因是,WebMethod的返回参数与入口参数为参数列表,所以当存在变更时,特别麻烦,需要修改WebService接口,客户端也要重新刷新WebService代理。所以这一次,改进了WebService的接口,所有的方法只有一个返回参数,一个入口参数。

       修改接口如下:

public interface IDALProvider

    {

        SelectResult Select(SelectParam para);

        UpdateResult Update(UpdateParam para);

        UpdateResult UpdateByDataSet(UpdateEntityPara para);

}

其中:SelectResultSelectParamUpdateResultUpdateParamUpdateResultUpdateEntityPara为参数类.主要封装了之前用到的参数列表,使更好的适应变化。

 

[Serializable]

    public class SelectParam : BaseUpdateParameters

    {

        #region Constructor

 

        public SelectParam()

        {

        }

        public SelectParam(string typeName,string cmdText,CommandType cmdType,ParametersCollection paras)

        {

            this._cmdtype = cmdType;

            this._cmdtext = cmdText;

            this.TypeName = typeName;

            this._collection = paras;

        }

 

        #endregion

    }

 

[Serializable]

    public class SelectResult : BaseSelectResult

    {

}

 

[Serializable]

    public class UpdateParam : BaseUpdateParameters

    {

}

 

[Serializable]

    public class UpdateResult : BaseUpdateResult

    {

}

 

Web服务代码如下:

[WebService(Namespace = "http://w3c.org/")]

[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]

public class DALService : System.Web.Services.WebService , IDALProvider

{

    #region Constructor

    public DALService()

    {

        //如果使用设计的组件,请取消注释以下行

        //InitializeComponent();

    }

    #endregion

 

    #region Fields

    private FY.SEL.WMS.DAL.DALService _provider;

    #endregion

 

    #region WebMethod

 

    #region IDALProvider 成员

 

    [WebMethod]

    public SelectResult Select(SelectParam para)

    {

        return Provider.Select(para);

    }

 

    [WebMethod]

    public UpdateResult Update(UpdateParam para)

    {

        return Provider.Update(para);

    }

 

    [WebMethod]

    public UpdateResult UpdateByDataSet(UpdateEntityPara para)

    {

        return Provider.UpdateByDataSet(para);

    }

 

    #endregion

 

    #endregion

 

    #region Properties

 

    protected FY.SEL.WMS.DAL.DALService Provider

    {

        get

        {

            if (this._provider == null)

            {

                this._provider = new FY.SEL.WMS.DAL.DALService();

            }

            return this._provider;

        }

    }

    #endregion

}

FY.SEL.WMS.DAL.DALService是一层代理,方便以后如果需要压缩,加密(解压缩,解密)返回参数,入口参数时扩展。

public class DALService : IDALProvider

    {

        #region IDALProvider 成员

        public SelectResult Select(SelectParam para)

        {

            IDALProvider provider = DALProviderFactory.CreateProvider(para.TypeName);

            return provider.Select(para);

        }

 

        public UpdateResult Update(UpdateParam para)

        {

IDALProvider provider = DALProviderFactory.CreateProvider(para.TypeName);

            return provider.Update(para);

        }

 

        public UpdateResult UpdateByDataSet(UpdateEntityPara para)

        {

            IDALProvider provider = DALProviderFactory.CreateProvider(para.TypeName);

            return provider.UpdateByDataSet(para);

        }

        #endregion

}

这样的设计,如果需要扩展参数时,只需要相应的在参数类中,增加对应的属性即可。(客户端引用WebService后,请把自动生成的参数类删除,加上参数类的引用即可,这样,参数类的变更,无需更新WebService引用)。

DALProviderFactory为简单工厂,创建对应数据层的子类。这里的改进是加入一个字典,缓存子类的实例,减少多次实例化。

public static class DALProviderFactory

    {

 

        #region Fields

        private const string Material = "Material";  //例子

        [ThreadStatic]

        private static IDictionary<string, IDALProvider> _cache;

        #endregion

        public static IDALProvider CreateProvider(string type)

        {

            return InnerCreateInstance(type);

        }

        private static IDALProvider InnerCreateInstance(string type)

        {

            IDALProvider result = null;

            if (DataProvider.ContainsKey(type))   //查找是否存在

            {

                result = _cache[type];

            }

            else

            {

                switch (type)

                {

                    case Material:         //例子

                        result=new MaterialDAL();

                        DataProvider[type] = result;

                        break;             

                    default:

                        throw new Exception("无法创建DAL对象");

                }

            }

            return result;

        }

        #region Properties

 

        private static IDictionary<string, IDALProvider> DataProvider

        {

            get

            {

                if (_cache == null)

                {

                    _cache= new Dictionary<string, IDALProvider>();

                }

                return _cache;

            }

        }

 

        #endregion

}

数据访问层没有实质的改动,请参看第一篇。WebService后台的改进大致如此。改进了参数类,有效的解决了参数的变更时变化。这样的设计也适合小项目使用,但是就接口而言,设计太粗,粒度太粗,耦合太强,不适合大中型项目。数据更新也主要采用DataSet,对于和其它平台交互有很大的影响。下一篇将讲一合适的WebService设计,粒度较细,层次更清晰。