如何使现有的 C# dll 作为 Web 服务可用
How to make an existing C# dll available as a web service
原则上这看起来很简单,但我想知道是否有人可以指导我完成基本步骤?
我有一个应用程序 API,在应用程序解决方案中作为 C# class 库项目实现。因此,人们可以通过直接引用 dll 来使用此 API 编写自己的常规 .Net 应用程序。
我现在需要提供 完全相同的功能 作为 Web 服务,以便编写应用程序以通过 http 远程访问相同的 API。理想情况下,我只想用适当的 Web 服务属性标记 API classes 和方法,但我怀疑还有更多。我还 必须 让 API dll 像现在一样继续作为桌面应用程序的 API 工作。
这可行吗?如果可以,我需要采取哪些步骤?
Web 服务主要由包装方法组成。以简单的案例为例...
如果您的 API 程序集中的方法是
public void DoFoo(string bar)
然后您的网络 API 方法(您选择的实现方式,例如 WebAPI、ASMX 网络服务等)将如下所示
public void DoFoo(string bar) {
// ... initialization or validation
try {
refToDll.DoFoo(bar);
} catch (Exception e) {
// implementation specific return of error.
}
}
如果您主要使用静态方法或采用原始类型的方法,那将变得更加容易。如果您的 API 定义了类型,这将变得更加困难。您将需要更改类型签名和重新实现方法。没有你的 API 就很难提出具体的建议。但是,有几种选择。如果你有
public class BazClass {
public string GetScore() {
return scores.Sum();
}
}
您基本上需要确保远程端(网络 API)可以从您的客户端重建上下文。您必须传入 BazClass
的可序列化实例或其他表示,并让远程 API 对其进行处理。它只是不存在。您还可以创建一堆在服务器上存储状态的方法,并在客户端使用 "handle" 或对象引用,但这必须是一个设计决策(只需查看与本机库的互操作,并处理,并转换为跨网络)。示例:
public string BazGetScore(Transport.BazClass baz) {
// Depending on the framework and class (all public getters/setters)?
// your framework may allow for transparent serialization
BazClass bazReal = bazFactory(baz);
string score = bazReal.GetScore();
return score;
}
您的源代码 API 中有多少是基于界面的?这可能会使代理 class 的创建对您的最终用户更加透明。如果你有
public class Baz : IBaz { ... }
然后您可以创建一个代理 class,其行为与 IBaz
类似,但调用远程 API 而不是本地行为。根据您的框架和工具,这些工具可能会促进这一点。
namespace RemoteAPIProxy {
public class Baz : IBaz {
public string GetScore() {
// initialization of network, API, etc
Transport.Baz baz = new Transport.Baz.From(this);
string score = CallRemoteAPI("BazGetScore", baz);
return score;
}
}
}
总而言之,您可能需要制作一些中间 classes,具体取决于您是否需要支持状态、非 public 方法或完整范围。 "how" 大多数情况下可以被认为只是另一个包装器,但您需要意识到如何通过线路获取本地状态并将其放入远程 API 的上下文中。使用接口、序列化助手和轻量级状态传输对象来帮助 "glue"。请记住,"API" 中唯一的 "I" 是给 "Interface" 的,因此您可能需要确保自己有一些。祝你好运!
原则上这看起来很简单,但我想知道是否有人可以指导我完成基本步骤?
我有一个应用程序 API,在应用程序解决方案中作为 C# class 库项目实现。因此,人们可以通过直接引用 dll 来使用此 API 编写自己的常规 .Net 应用程序。
我现在需要提供 完全相同的功能 作为 Web 服务,以便编写应用程序以通过 http 远程访问相同的 API。理想情况下,我只想用适当的 Web 服务属性标记 API classes 和方法,但我怀疑还有更多。我还 必须 让 API dll 像现在一样继续作为桌面应用程序的 API 工作。
这可行吗?如果可以,我需要采取哪些步骤?
Web 服务主要由包装方法组成。以简单的案例为例...
如果您的 API 程序集中的方法是
public void DoFoo(string bar)
然后您的网络 API 方法(您选择的实现方式,例如 WebAPI、ASMX 网络服务等)将如下所示
public void DoFoo(string bar) {
// ... initialization or validation
try {
refToDll.DoFoo(bar);
} catch (Exception e) {
// implementation specific return of error.
}
}
如果您主要使用静态方法或采用原始类型的方法,那将变得更加容易。如果您的 API 定义了类型,这将变得更加困难。您将需要更改类型签名和重新实现方法。没有你的 API 就很难提出具体的建议。但是,有几种选择。如果你有
public class BazClass {
public string GetScore() {
return scores.Sum();
}
}
您基本上需要确保远程端(网络 API)可以从您的客户端重建上下文。您必须传入 BazClass
的可序列化实例或其他表示,并让远程 API 对其进行处理。它只是不存在。您还可以创建一堆在服务器上存储状态的方法,并在客户端使用 "handle" 或对象引用,但这必须是一个设计决策(只需查看与本机库的互操作,并处理,并转换为跨网络)。示例:
public string BazGetScore(Transport.BazClass baz) {
// Depending on the framework and class (all public getters/setters)?
// your framework may allow for transparent serialization
BazClass bazReal = bazFactory(baz);
string score = bazReal.GetScore();
return score;
}
您的源代码 API 中有多少是基于界面的?这可能会使代理 class 的创建对您的最终用户更加透明。如果你有
public class Baz : IBaz { ... }
然后您可以创建一个代理 class,其行为与 IBaz
类似,但调用远程 API 而不是本地行为。根据您的框架和工具,这些工具可能会促进这一点。
namespace RemoteAPIProxy {
public class Baz : IBaz {
public string GetScore() {
// initialization of network, API, etc
Transport.Baz baz = new Transport.Baz.From(this);
string score = CallRemoteAPI("BazGetScore", baz);
return score;
}
}
}
总而言之,您可能需要制作一些中间 classes,具体取决于您是否需要支持状态、非 public 方法或完整范围。 "how" 大多数情况下可以被认为只是另一个包装器,但您需要意识到如何通过线路获取本地状态并将其放入远程 API 的上下文中。使用接口、序列化助手和轻量级状态传输对象来帮助 "glue"。请记住,"API" 中唯一的 "I" 是给 "Interface" 的,因此您可能需要确保自己有一些。祝你好运!