簡體   English   中英

從現有API自動生成服務器端WCF服務

[英]Generate Server Side WCF Service automatically from existing API

如何在不使用WCF項目的情況下,通過WCF將每個方法的API暴露給由多個類組成的API。

例如,假設我有以下內容

public interface RainfallMonitor
{
    [ExposeToWeb]
    void RecordRainfall(string county, float rainfallInches);

    [ExposeToWeb]
    float GetTotalRainfall(string county);

    void ClearRainfall(string county);
}

我知道我可以像往常一樣創建一個WCF服務庫,只需添加一個名為“RainfallMonitor”的WCF服務。

我正在探索的是......是否可能/合理地在編譯時為整個API生成所有WCF相關代碼而不實際生成類WCF服務。 可能使用ExposeToWeb等屬性來表示通過服務公開哪些方法。 結果將像這樣:

  1. 在名為RainfallAPI項目中創建/修改類
  2. 編譯並自動生成另一個名為RainfallService項目/ dll。

實質上:

  • 如果可行,我可以采取什么方法來實際實施呢?
  • 我可能遇到什么嚴重的陷阱?
  • 是否有任何現有的代碼庫可以做類似的事情我可以尋找靈感

為了澄清:我不是在問自動生成客戶端存根,我問的是在服務器端創建服務。

我最近是這個圖書館的負責人: Fody 據我所知,它可以掛鈎構建過程並將IL注入到程序集中。 我不完全確定它是如何工作的,但是有可能通過IL搜索,找到具有ExposeToWeb屬性的所有方法並使用它來將WCF服務的合同發送到程序集中。

但另一方面,如果您已經在類中添加了屬性,為什么不直接添加正確的WFC屬性,然后使用SvcUtil在post build中生成合同?

編輯:這是一個如何使用svcutil的示例:

C#:

[ServiceContract]
public interface IRainfallMonitor
{
    [OperationContract]
    void RecordRainfall(string county, float rainfallInches);
}

public class RainfallMonitor : IRainfallMonitor
{
    public void RecordRainfall(string county, float rainfallInches)
    {
        // code
    }
}

post build PowerShell:

$svcutil = "C:\Program Files (x86)\Microsoft SDKs\Windows\v8.0A\bin\NETFX 4.0 Tools\SvcUtil.exe"
$csc = "C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe"
$assembly = "bin/debug/ProjectWithoutWCF.dll"
$service = "ProjectWithoutWCF.RainfallMonitor"
$outputns = "ProjectWithoutWCF.RainfallMonitor.Service"
$outputdir = "bin/debug"

md svcutil_tmp
cd svcutil_tmp

& $svcutil /serviceName:"$service" "../$assembly"
& $svcutil *.wsdl *.xsd /importxmltypes /out:"output.cs" /n:"*,$outputns"
& $csc /target:library /out:$outputns.dll "output.cs"

cp "$outputns.dll" "../$outputdir"
cp output.config "../$outputdir/$outputns.dll.config"
cd ..
rm -r .\svcutil_tmp

在項目配置中你需要這樣的東西:

<system.serviceModel>
  <services>
    <service name="ProjectWithoutWCF.RainfallMonitor" >
      <endpoint address="" binding="basicHttpBinding" contract="ProjectWithoutWCF.IRainfallMonitor">
      </endpoint>
    </service>
  </services>
</system.serviceModel>

它有點繁瑣,你很可能需要對腳本和配置進行一些調整。 但結果是你有一個帶有WCF服務合同的ProjectWithoutWCF.RainfallMonitor.Service.dll文件。

關於“我正在探索的是......是否可能/合理地在編譯時為整個API生成所有WCF相關代碼而不實際生成類WCF服務的可能/合理。”,有選項,但是他們都會做很多工作。

您需要編寫一個代碼生成應用程序/庫,它使用CSharpCodeProvider等類(也有一個用於VB)和反射來檢查您的庫作為后期構建步驟,在內存中構建您想要的代碼,並保存它作為DLL關閉。

此應用程序需要找到您創建的自定義屬性,指示它應該是WCF服務,並根據您定義的規則輸出WCF代碼。

實際上,您需要使用CodeDOM模型編寫代碼,這需要以非常不同的方式思考代碼。 不是每個人都能夠將他們的思想抽象到那個層次。

請記住,利用CodeDOM模型,您可以克服點頭提到的一些問題,例如要求可序列化的數據合同。 這可以添加,並由基於CodeDOM的反射庫輸出新的DLL。

通過周到的設計和相當多的工作,可以實現您正在尋求的輸出。 這只是一條黑暗的道路,有很多陷阱可以到達那里。

是的,這可以通過使用正確的工具進行適度的努力來完成。 如果您有Visual Studio,則您已經擁有Microsoft的T4代碼生成器。 它允許您通過編寫“文本模板”來生成代碼,這非常讓人聯想到ASP.NET的RAZOR語法。 使用T4,您實際上可以實例化現有類並使用反射來讀取所有類名和方法簽名,並最終生成WCF服務。 這並不難!

以下是Oleg Sych教程中的 T4模板示例:

<#@ template language=“C#v3.5” #>
<#@ output extension=“SQL” #>
<#@ assembly name=“Microsoft.SqlServer.ConnectionInfo” #>
<#@ assembly name=“Microsoft.SqlServer.Smo” #>
<#@ import namespace=“Microsoft.SqlServer.Management.Smo” #>
<#
    Server server = new Server();
    Database database = new Database(server, “Northwind”);
    Table table = new Table(database, “Products”);
    table.Refresh();
#>
create procedure <#= table.Name #>_Delete
<#
    PushIndent(”\t”);
    foreach (Column column in table.Columns)
    {
        if (column.InPrimaryKey)
            WriteLine(”@” + column.Name + ” ” + column.DataType.Name);
    }
    PopIndent();
#>
as
    delete from <#= table.Name #>
    where
<#
    PushIndent(”\t\t”);
    foreach (Column column in table.Columns)
    {
        if (column.InPrimaryKey)
            WriteLine(column.Name + ” = @” + column.Name);
    }
    PopIndent();
#>

輸出看起來像這樣:

create procedure Products_Delete
    @ProductID int
as
    delete from Products
    where ProductID = @ProductID

當然,在您的示例中,您將使用現有類庫的反射而不是sql查詢。 您生成的WCf服務可以簡單地調用您現有的庫,這樣您就不必復制所有實際的域邏輯。

MSDN

https://msdn.microsoft.com/en-us/library/bb126445.aspx

您可以使用Roslyn,Roslyn是新的編譯器作為服務,您可以在其中解析C#文件並根據需要生成源代碼。

你可以在這里看到一些例子,

http://www.codeproject.com/Articles/302595/Roslyn-CTP-Three-Introductory-Projects

應該不那么困難。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM