二10、【.Net開源】EFW框架核心類庫之WebService服務

回《【開源】EFW框架系列文章索引》       html

EFW框架源代碼下載V1.1:http://pan.baidu.com/s/1qWJjo3Uweb

EFW框架實例源代碼下載:http://pan.baidu.com/s/1o6MAKCa數據庫

 

       EFW框架中的WebService服務開發方式與傳統的net項目中開發不太同樣,傳統的開發方式雖然也挺簡單但在後面的發佈部署仍是挺麻煩的,而在EFW框架中開發Webservice就跟編寫普通的C#代碼同樣,並不須要單獨建WebService服務項目,不須要Asmx文件;因此發佈WebService只要把編譯好的Dll拷貝到Web程序目錄中就好了;c#

       另外我建議儘可能少用WebService服務來開發業務功能,系統內部的功能實現用前三章的控制器方式就能夠搞定,只有在須要與外部系統作接口時,能夠用它來開發相關接口程序;設計模式

本章主要內容經過解讀框架源代碼來學習WebService服務是怎麼實現的,以及學習這種設計模式;服務器

本文要點:app

1.如何開發WebService系統接口框架

2.WebService服務的設計思路async

3.WebService服務基類的AbstractService的實現ide

4.經過服務名稱解析WebService對象的WebServiceInvoker類的實現

5.利用wsdl生成WebService生成代理類

WebService服務源代碼目錄結構:

 

EFW框架控制器設計圖:

 

 

1.如何開發WebService系統接口

 

如上圖,Books項目中實現了書籍實例的一些Webservice系統接口,bookWebService.cs文件是和邏輯層代碼放在一塊兒的,並不須要單獨建一個Webservice服務項目,也不須要建到Web項目中;對比一下上圖普通的WebService服務,不須要BookService.asmx文件;

 

見上圖,WebService服務接口的使用跟普通的Net 系統中的WebService是同樣的,地址欄中輸入WebService服務對象的名稱就能夠調用,可是注意名稱同樣可是必須用asmx爲後綴名,由於服務器只解析這種後綴名稱的文件映射到後臺的WebService服務;上圖開放了兩個WebService服務方法SaveBook和SearchBook。

 

2.WebService服務的設計思路

       當初設計這種開發模式的目的就是爲了減小項目的個數,到如今整個框架的項目只有5個,並且只有5個項目卻包括了Web、Winform和WCF三種系統的開發;這都是爲了秉承框架中的核心思想「簡潔」,結構的簡單明瞭,代碼的整潔乾淨;因此爲了幾個WebService接口而增長一個WebService項目以爲太划不來了,因此開始思考如何實現,後來在網上看到了一個帖子講動態調用WebService服務的,具體哪一個帖子如今找不到了,反正我就借鑑了過來融入到了框架中,終於解決了這個難題;WebServiceInvoker類就是動態解析WebService服務的實現代碼;全部WebService服務對象都必須繼承AbstractService基類,AbstractService基類封裝了WebService服務公共的處理功能;

 

3.WebService服務基類的AbstractService的實現

AbstractService文件

 1   /// <summary>
 2     /// WebService基類
 3     /// </summary>
 4     public class AbstractService : WebService, INewObject, INewDao
 5     {
 6 
 7         private AbstractDatabase _oleDb = null;
 8         private IUnityContainer _container = null;
 9         public AbstractDatabase oleDb
10         {
11             get
12             {
13                 if (_oleDb == null)
14                 {
15                     _oleDb = FactoryDatabase.GetDatabase();
16                     _container = AppGlobal.container;
17                 }
18                 return _oleDb;
19             }
20         }
21 
22         //聲明Soap頭實例
23         public GlobalParam param = new GlobalParam();
24 
25         #region IBindDb 成員
26 
27         public void BindDb(AbstractDatabase Db, IUnityContainer container)
28         {
29             _oleDb = Db;
30             _container = container;
31         }
32 
33         public T BindDb<T>(T model)
34         {
35             (model as IbindDb).BindDb(_oleDb, _container);
36             return model;
37         }
38 
39         public List<T> ListBindDb<T>(List<T> list)
40         {
41             for (int i = 0; i < list.Count; i++)
42             {
43                 (list[i] as IbindDb).BindDb(_oleDb, _container);
44             }
45             return list;
46         }
47 
48         public AbstractDatabase GetDb()
49         {
50             return _oleDb;
51         }
52 
53         public IUnityContainer GetUnityContainer()
54         {
55             return _container;
56         }
57 
58         #endregion
59 
60         #region INewObject 成員
61         public T NewObject<T>()
62         {
63             T t = FactoryModel.GetObject<T>(_oleDb, _container, null);
64             return t;
65         }
66 
67         public T NewObject<T>(string unityname)
68         {
69             T t = FactoryModel.GetObject<T>(_oleDb, _container, unityname);
70             return t;
71         }
72 
73         #endregion
74 
75         #region INewDao 成員
76 
77         public T NewDao<T>()
78         {
79             T t = FactoryModel.GetObject<T>(_oleDb, _container, null);
80             return t;
81         }
82 
83         public T NewDao<T>(string unityname)
84         {
85             T t = FactoryModel.GetObject<T>(_oleDb, _container, unityname);
86             return t;
87         }
88 
89         #endregion
90 
91     }
View Code

 

AbstractService基類的功能封裝包括:

1)數據庫操做對象oleDb,能夠直接在WebService服務中編寫SQL語句操做數據庫

2)實例化ObjectModel對象和Dao對象的方法,在WebService服務中實例化對象不能用new關鍵字,只能用NewObject()和NewDao()內置方法;

 

4.經過服務名稱解析WebService對象的WebServiceInvoker類的實現

WebServiceInvoker文件

 1 /// <summary>
 2     /// WebService處理對象
 3     /// </summary>
 4     public class WebServiceInvoker : IHttpHandlerFactory
 5     {
 6         private Type GetWebService(HttpRequest request, string serviceName)
 7         {
 8             Type serviceType = null;
 9             //for (int i = 0; i < AppGlobal.BusinessDll.Count; i++)
10             //{
11             //    Assembly asmb = Assembly.LoadFrom(AppGlobal.AppRootPath + "bin\\" + AppGlobal.BusinessDll[i].Trim());
12             //    if (asmb != null)
13             //    {
14             //        Type ts = asmb.GetType(serviceName);
15             //        if (ts != null)
16             //        {
17             //            serviceType = ts;
18             //            break;
19             //        }
20             //    }
21             //}
22 
23             List<Type> cmd = (List<Type>)AppGlobal.cache.GetData("cmdWebService");
24             serviceType = cmd.Find(x => x.Name == serviceName);
25             return serviceType;
26         }
27 
28         public void ReleaseHandler(IHttpHandler handler)
29         {
30             var wshf = new System.Web.Services.Protocols.WebServiceHandlerFactory();
31             wshf.ReleaseHandler(handler);
32         }
33 
34         public IHttpHandler GetHandler(HttpContext context, string requestType, string url, string pathTranslated)
35         {
36             var webServiceType = GetWebService(context.Request, GetServiceName(url));
37             var wshf = new System.Web.Services.Protocols.WebServiceHandlerFactory();
38             var coreGetHandler = typeof(WebServiceHandlerFactory).GetMethod("CoreGetHandler", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
39             var httpHandler = (IHttpHandler)coreGetHandler.Invoke(wshf, new object[] { webServiceType, context, context.Request, context.Response });
40             return httpHandler;
41         }
42 
43         public static string GetServiceName(string url)
44         {
45             int index = url.LastIndexOf("/");
46             int index2 = url.Substring(index).IndexOf(".");
47             return url.Substring(index + 1, index2 - 1);
48         }
49 
50         public static void LoadWebService(List<string> BusinessDll, ICacheManager cache)
51         {
52             List<Type> webserviceList = new List<Type>();
53 
54             for (int k = 0; k < BusinessDll.Count; k++)
55             {
56                 System.Reflection.Assembly assembly = System.Reflection.Assembly.LoadFrom(EFWCoreLib.CoreFrame.Init.AppGlobal.AppRootPath + "bin/" + BusinessDll[k]);
57                 Type[] types = assembly.GetTypes();
58                 for (int i = 0; i < types.Length; i++)
59                 {
60                     WebServiceAttribute[] webS = ((WebServiceAttribute[])types[i].GetCustomAttributes(typeof(WebServiceAttribute), true));
61                     if (webS.Length > 0)
62                     {
63                         webserviceList.Add(types[i]);
64                     }
65                 }
66             }
67 
68             cache.Add("cmdWebService", webserviceList);
69         }
70     }
View Code

 

WebServiceInvoker對象繼承IHttpHandlerFactory接口並實現接口方法GetHandler和ReleaseHandler,還要在Web.Config配置文件中進行配置;

 

5.利用wsdl生成WebService生成代理類

生成命令:wsdl /language:c# /out:c:\bookWebService.cs http://localhost:51796/bookWebService.asmx?WSDL

操做步驟:

1)打開Net命令工具

 

2)複製上面的wsdl命令並執行,提示寫入「c:\bookWebService.cs 」成功

 

3)再把「c:\bookWebService.cs 」的文件拷貝到須要調用WebService接口的項目中使用就能夠了;

bookWebService文件

//------------------------------------------------------------------------------
// <auto-generated>
//     此代碼由工具生成。
//     運行時版本:2.0.50727.5477
//
//     對此文件的更改可能會致使不正確的行爲,而且若是
//     從新生成代碼,這些更改將會丟失。
// </auto-generated>
//------------------------------------------------------------------------------

using System;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Xml.Serialization;

// 
// 此源代碼由 wsdl 自動生成, Version=2.0.50727.1432。
// 


/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.1432")]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Web.Services.WebServiceBindingAttribute(Name="bookWebServiceSoap", Namespace="http://tempuri.org/")]
[System.Xml.Serialization.XmlIncludeAttribute(typeof(MarshalByRefObject))]
public partial class bookWebService : System.Web.Services.Protocols.SoapHttpClientProtocol {
    
    private System.Threading.SendOrPostCallback SaveBookOperationCompleted;
    
    private System.Threading.SendOrPostCallback SearchBookOperationCompleted;
    
    /// <remarks/>
    public bookWebService() {
        this.Url = "http://localhost:51796/bookWebService.asmx";
    }
    
    /// <remarks/>
    public event SaveBookCompletedEventHandler SaveBookCompleted;
    
    /// <remarks/>
    public event SearchBookCompletedEventHandler SearchBookCompleted;
    
    /// <remarks/>
    [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://tempuri.org/SaveBook", RequestNamespace="http://tempuri.org/", ResponseNamespace="http://tempuri.org/", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
    public void SaveBook(Book book) {
        this.Invoke("SaveBook", new object[] {
                    book});
    }
    
    /// <remarks/>
    public System.IAsyncResult BeginSaveBook(Book book, System.AsyncCallback callback, object asyncState) {
        return this.BeginInvoke("SaveBook", new object[] {
                    book}, callback, asyncState);
    }
    
    /// <remarks/>
    public void EndSaveBook(System.IAsyncResult asyncResult) {
        this.EndInvoke(asyncResult);
    }
    
    /// <remarks/>
    public void SaveBookAsync(Book book) {
        this.SaveBookAsync(book, null);
    }
    
    /// <remarks/>
    public void SaveBookAsync(Book book, object userState) {
        if ((this.SaveBookOperationCompleted == null)) {
            this.SaveBookOperationCompleted = new System.Threading.SendOrPostCallback(this.OnSaveBookOperationCompleted);
        }
        this.InvokeAsync("SaveBook", new object[] {
                    book}, this.SaveBookOperationCompleted, userState);
    }
    
    private void OnSaveBookOperationCompleted(object arg) {
        if ((this.SaveBookCompleted != null)) {
            System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg));
            this.SaveBookCompleted(this, new System.ComponentModel.AsyncCompletedEventArgs(invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState));
        }
    }
    
    /// <remarks/>
    [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://tempuri.org/SearchBook", RequestNamespace="http://tempuri.org/", ResponseNamespace="http://tempuri.org/", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
    public System.Data.DataTable SearchBook(string schar, int flag) {
        object[] results = this.Invoke("SearchBook", new object[] {
                    schar,
                    flag});
        return ((System.Data.DataTable)(results[0]));
    }
    
    /// <remarks/>
    public System.IAsyncResult BeginSearchBook(string schar, int flag, System.AsyncCallback callback, object asyncState) {
        return this.BeginInvoke("SearchBook", new object[] {
                    schar,
                    flag}, callback, asyncState);
    }
    
    /// <remarks/>
    public System.Data.DataTable EndSearchBook(System.IAsyncResult asyncResult) {
        object[] results = this.EndInvoke(asyncResult);
        return ((System.Data.DataTable)(results[0]));
    }
    
    /// <remarks/>
    public void SearchBookAsync(string schar, int flag) {
        this.SearchBookAsync(schar, flag, null);
    }
    
    /// <remarks/>
    public void SearchBookAsync(string schar, int flag, object userState) {
        if ((this.SearchBookOperationCompleted == null)) {
            this.SearchBookOperationCompleted = new System.Threading.SendOrPostCallback(this.OnSearchBookOperationCompleted);
        }
        this.InvokeAsync("SearchBook", new object[] {
                    schar,
                    flag}, this.SearchBookOperationCompleted, userState);
    }
    
    private void OnSearchBookOperationCompleted(object arg) {
        if ((this.SearchBookCompleted != null)) {
            System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg));
            this.SearchBookCompleted(this, new SearchBookCompletedEventArgs(invokeArgs.Results, invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState));
        }
    }
    
    /// <remarks/>
    public new void CancelAsync(object userState) {
        base.CancelAsync(userState);
    }
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.1432")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://tempuri.org/")]
public partial class Book : AbstractEntity {
    
    private int idField;
    
    private string bookNameField;
    
    private decimal buyPriceField;
    
    private System.DateTime buyDateField;
    
    private int flagField;
    
    /// <remarks/>
    public int Id {
        get {
            return this.idField;
        }
        set {
            this.idField = value;
        }
    }
    
    /// <remarks/>
    public string BookName {
        get {
            return this.bookNameField;
        }
        set {
            this.bookNameField = value;
        }
    }
    
    /// <remarks/>
    public decimal BuyPrice {
        get {
            return this.buyPriceField;
        }
        set {
            this.buyPriceField = value;
        }
    }
    
    /// <remarks/>
    public System.DateTime BuyDate {
        get {
            return this.buyDateField;
        }
        set {
            this.buyDateField = value;
        }
    }
    
    /// <remarks/>
    public int Flag {
        get {
            return this.flagField;
        }
        set {
            this.flagField = value;
        }
    }
}

/// <remarks/>
[System.Xml.Serialization.XmlIncludeAttribute(typeof(Book))]
[System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.1432")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://tempuri.org/")]
public abstract partial class AbstractEntity : AbstractBusines {
}

/// <remarks/>
[System.Xml.Serialization.XmlIncludeAttribute(typeof(AbstractEntity))]
[System.Xml.Serialization.XmlIncludeAttribute(typeof(Book))]
[System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.1432")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://tempuri.org/")]
public abstract partial class AbstractBusines : MarshalByRefObject {
}

/// <remarks/>
[System.Xml.Serialization.XmlIncludeAttribute(typeof(AbstractBusines))]
[System.Xml.Serialization.XmlIncludeAttribute(typeof(AbstractEntity))]
[System.Xml.Serialization.XmlIncludeAttribute(typeof(Book))]
[System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.1432")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://tempuri.org/")]
public abstract partial class MarshalByRefObject {
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.1432")]
public delegate void SaveBookCompletedEventHandler(object sender, System.ComponentModel.AsyncCompletedEventArgs e);

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.1432")]
public delegate void SearchBookCompletedEventHandler(object sender, SearchBookCompletedEventArgs e);

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.1432")]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
public partial class SearchBookCompletedEventArgs : System.ComponentModel.AsyncCompletedEventArgs {
    
    private object[] results;
    
    internal SearchBookCompletedEventArgs(object[] results, System.Exception exception, bool cancelled, object userState) : 
            base(exception, cancelled, userState) {
        this.results = results;
    }
    
    /// <remarks/>
    public System.Data.DataTable Result {
        get {
            this.RaiseExceptionIfNecessary();
            return ((System.Data.DataTable)(this.results[0]));
        }
    }
}
View Code
相關文章
相關標籤/搜索