2015-06-23 13 views
13

Làm thế nào một người tiếp cận phương pháp trưng bày cho mỗi phương thức mà API bao gồm một số lớp thông qua WCF mà không cần sử dụng dự án WCF.Tự động tạo dịch vụ WCF phía máy chủ tự động từ API hiện tại

Ví dụ, giả sử tôi có sau

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

    [ExposeToWeb] 
    float GetTotalRainfall(string county); 

    void ClearRainfall(string county); 
} 

Tôi hiểu rằng tôi có thể tạo ra một thư viện dịch vụ WCF như bình thường và chỉ cần thêm một dịch vụ WCF gọi là "RainfallMonitor".

Điều tôi đang khám phá là ... có thể hợp lý bằng cách nào đó tạo ra tất cả mã liên quan WCF tại thời gian biên dịch cho toàn bộ API mà không thực sự tạo các dịch vụ WCF cho lớp học. Có thể sử dụng các thuộc tính như ExposeToWeb để biểu thị phương thức nào hiển thị thông qua dịch vụ. Các kết quả sẽ hoạt động như thế này:

  1. Tạo/sửa đổi các lớp học trong dự án có tên RainfallAPI
  2. Compile và có một dự án/dll được tạo ra gọi là RainfallService tự động.

Về cơ bản:

  • Nếu đây là có thể tiếp cận những gì tôi có thể làm để thực sự thực hiện nó?
  • Tôi có thể gặp phải những cạm bẫy nghiêm trọng nào?
  • Có codebase hiện có mà làm điều gì đó tương tự như tôi có thể nhìn vào cảm hứng

Để làm rõ: Tôi không yêu cầu về tự động tạo stub client, tôi đang hỏi về việc tạo ra các dịch vụ trên phía máy chủ.

+2

Tôi có thể nghĩ đến hai vấn đề tiềm ẩn ở phía trên đầu của tôi: 1) Quá tải phương thức không thể được ánh xạ 1: 1 thành nhiều OperationContracts (tên phải khác nhau). 2) Tất cả các kiểu phức tạp được sử dụng trong API phải được tuần tự hóa (ví dụ như [DataContracts]), vì vậy các tác giả API phải biết rằng API của chúng sẽ được hiển thị dưới dạng các dịch vụ WCF. – nodots

Trả lời

0

Đối với câu hỏi của bạn về "Những gì tôi đang khám phá ... là có thể/hợp lý bằng cách nào đó tạo ra tất cả mã liên quan WCF tại thời gian biên dịch cho toàn bộ API mà không thực sự tạo các dịch vụ WCF cho lớp học." là những lựa chọn, nhưng tất cả họ sẽ mất rất nhiều công sức.

Bạn cần phải viết một ứng dụng/thư viện tạo mã sử dụng các lớp như CSharpCodeProvider (có một cho VB) và phản ánh để kiểm tra thư viện của bạn dưới dạng bước đăng bài, xây dựng mã bạn muốn trong bộ nhớ và lưu nó dưới dạng tệp DLL.

Ứng dụng này sẽ cần phải tìm thuộc tính tùy chỉnh mà bạn tạo cho biết rằng đó phải là dịch vụ WCF và xuất mã WCF dựa trên các quy tắc bạn xác định.

Có hiệu lực bạn cần phải viết mã bằng cách sử dụng mô hình CodeDOM, yêu cầu suy nghĩ về mã theo một phong cách khác. Không phải ai cũng có thể trừu tượng suy nghĩ của họ đến mức đó.

Hãy nhớ rằng sử dụng mô hình CodeDOM, bạn có thể khắc phục một số vấn đề mà các nút được đề cập như yêu cầu có thể tuần tự hóa cho các hợp đồng dữ liệu. Điều này có thể được thêm vào và một DLL mới được xuất ra bởi thư viện phản chiếu dựa trên CodeDOM của bạn.

Thông qua thiết kế chu đáo và khá nhiều công việc, bạn có thể đạt được kết quả bạn đang tìm kiếm. Nó chỉ là một con đường tối với rất nhiều cạm bẫy để đến đó.

1

Gần đây tôi đã đứng đầu thư viện này: Fody.Theo tôi hiểu, nó làm cho nó có thể móc vào quá trình xây dựng và tiêm IL vào lắp ráp. Tôi không hoàn toàn chắc chắn như thế nào nó hoạt động, nhưng nó có thể có thể tìm kiếm mặc dù IL, tìm tất cả các phương pháp với các thuộc tính ExposeToWeb và sử dụng để phát ra các hợp đồng cho các dịch vụ WCF vào lắp ráp.

Nhưng mặt khác, nếu bạn đã thêm thuộc tính vào lớp, tại sao không chỉ thêm thuộc tính WFC chính xác để bắt đầu, sau đó sử dụng SvcUtil để tạo hợp đồng trong bài đăng?

EDIT: Dưới đây là một ví dụ về cách bạn có thể sử dụng 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 
    } 
} 

bài 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 

và bạn sẽ cần một cái gì đó như thế này trong bạn cấu hình dự án:

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

Hơi khó sử dụng và bạn rất có thể sẽ cần một số chỉnh sửa đối với tập lệnh và cấu hình. Nhưng kết quả là bạn có một tệp ProjectWithoutWCF.RainfallMonitor.Service.dll với các hợp đồng dịch vụ WCF.

0

Có, điều này có thể được thực hiện, với nỗ lực vừa phải bằng cách sử dụng các công cụ phù hợp. Nếu bạn có Visual Studio, bạn đã có bộ tạo mã T4 của Microsoft. Nó cho phép bạn tạo mã bằng cách viết "các mẫu văn bản", rất gợi nhớ cú pháp RAZOR của ASP.NET. Sử dụng T4, bạn có thể thực sự khởi tạo các lớp hiện có của bạn và sử dụng sự phản chiếu để đọc tất cả các tên lớp và chữ ký phương thức, và cuối cùng tạo ra các dịch vụ WCF của bạn. Nó không phải là khó!

Đây là một mẫu T4 mẫu từ Oleg Sych's tutorial:

<#@ 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(); 
#> 

Sản lượng sẽ trông như thế này:

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

Tất nhiên, ví dụ, bạn muốn sử dụng phản ánh trên thư viện lớp hiện tại của bạn thay vì truy vấn sql. Các dịch vụ WCf mà bạn tạo ra chỉ đơn giản có thể gọi thư viện hiện có của bạn, để bạn không phải sao chép tất cả các logic miền thực tế.

MSDN

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

Các vấn đề liên quan