将参数从一个项目传递到另一个项目中的特定类
本文关键字:项目 另一个 一个 参数 | 更新日期: 2023-09-27 18:15:28
我刚开始为一个学校项目学习C#,但我遇到了一些问题。
我有一个包含2个项目的解决方案(每个项目都有一个类(,大致如下:
解决方案:
- 服务器(项目((…(MyServerClass.cs,Program.cs
- 应用程序(项目((…(MyAppClass.cs,Program.cs
在我的"MyServerClass.cs"中,我有这样的:
class MyServerClass
{
...
public void SomeMethod()
{
Process.Start("App.exe", "MyAppClass");
}
}
例如,如何正确发送IP地址和端口?像这样的东西行吗?
class MyServerClass
{
....
public void SomeMethod()
{
string ip = "127.0.0.1";
int port = 8888;
Process.Start("App.exe", "MyAppClass " + ip + " " + port);
}
}
然后在我的"MyAppClass.cs"中,我如何接收该IP地址和端口?
编辑:
这项工作的目标是练习进程/线程/套接字。这个想法是有一个服务器来接收电子邮件并过滤它们,以知道它们是否是垃圾邮件。我们必须有4或5个过滤器。我们的想法是将它们作为单独的项目(例如:Filter1.exe、Filter2.exe…(,但我试图只有一个项目(例如,Filters.exe(,并将过滤器作为类(Filter1.cs、Filter2.cs…(,然后为每个不同的过滤器创建一个新的进程。
我想我会为每个过滤器坚持一个项目!
谢谢!
有很多方法可以实现这一点,每种方法都有自己的优缺点。
一些可能的解决方案:
- 在命令行上传入值。优点:简单。缺点:发射时只能传递一次。单向(子进程无法发回信息(。对于复杂的结构化数据,不能很好地扩展
- 创建Web服务(在服务器或客户端中(。连接到它,然后拉动/推动适当的设置。优点:灵活、持续、潜在的双向,具有某种形式的轮询,如果客户端/服务器位于不同的主机上,则可以工作。缺点:有点复杂,需要一个应用程序能够定位另一个应用的网址,这在本地是微不足道的,而且更多地涉及网络
- 通过内存映射文件使用共享内存。这种方法允许多个进程访问相同的内存块。一个进程可以写入所需的数据,其他进程可以读取。优点:高效、双向,可以通过重新启动将磁盘备份到持久状态。缺点:需要指针并了解它们的工作原理。需要更多的数据操作才能执行读/写操作
还有几十种方法。如果不详细了解你的情况,很难推荐一个而不是另一个。
编辑回复:更新的要求
好的,这里的命令行绝对是个不错的选择。快速进入某些架构。。。
你没有理由不能用一个项目做到这一点。
首先,使用一个接口来确保所有过滤器都是可互换的。像这样的。。。
public interface IFilter {
FilterResult Filter(string email);
void SetConfig(string config);
}
SetConfig()
是可选的,但对于在不重新编译的情况下重新配置过滤器可能很有用。
你还需要决定你的IFilter的FilterResult
是什么。它是通过还是失败?还是得分?也许是一些标志和其他指标。
如果你想做多个项目,你会把这个接口放在一个";共享的";或";普通的";项目本身,并从其他项目中引用它。这也使得第三方开发过滤器变得容易。
不管怎样,下一个。让我们看看过滤器是如何托管的。你想要在网络上监听的东西,但这不是过滤器本身的责任,所以我们需要一个网络客户端。你在这里用什么取决于你。WCF在某种程度上似乎是一个主要的候选者。您的网络客户端类应该在其构造函数中包含一个要侦听的网络端口和一个筛选器实例。。。
public class NetworkClient {
private string endpoint;
private IFilter filter;
public NetworkClient(string Endpoint, IFilter Filter) {
this.filter = Filter;
this.endpoint = Endpoint;
this.Setup();
}
void Setup() {
// Set up your network client to listen on endpoint.
// When it receives a message, pass it to filter.Filter(msg);
}
}
最后,我们需要一个应用程序来承载所有内容。这取决于你是选择控制台应用程序还是winforms/wpf。取决于您是否希望进程具有GUI。如果它是作为服务运行的,那么用户界面无论如何都不会在用户桌面上可见。
因此,我们将有一个进程,该进程获取NetworkClient要侦听的端点、要使用的筛选器的类名,以及(可选(在首次使用之前传递给筛选器的配置字符串。
因此,在应用程序的Main()
中,执行以下操作。。。
static void Main() {
try {
const string usage = "Usage: Filter.exe Endpoint FilterType [Config]";
var args = Environment.GetCommandLineArgs();
Type filterType;
IFilter filter;
string endpoint;
string config = null;
NetworkClient networkClient;
switch (args.Length) {
case 0:
throw new InvalidOperationException(String.Format("{0}. An endpoint and filter type are required", usage));
case 1:
throw new InvalidOperationException(String.Format("{0}. A filter type is required", usage));
case 2:
// We've been given an endpoint and type
break;
case 3:
// We've been given an endpoint, type and config.
config = args[3];
break;
default:
throw new InvalidOperationException(String.Format("{0}. Max three parameters supported. If your config contains spaces, ensure you are quoting/escaping as required.", usage));
}
endpoint = args[1];
filterType = Type.GetType(args[2]); //Look at the overloads here to control where you're searching
// Now actually create an instance of the filter
filter = (IFilter)Activator.CreateInstance(filterType);
if (config != null) {
// If required, set config
filter.SetConfig(config);
}
// Make a new NetworkClient and tell it where to listen and what to host.
networkClient = new NetworkClient(endpoint, filter);
// In a console, loop here until shutdown is requested, however you've implemented that.
// In winforms, the main UI loop will keep you alive.
} catch (Exception e) {
Console.WriteLine(e.ToString()); // Or display a dialog
}
}
然后,您应该能够像这样调用您的流程。。。
Filter.exe "127.0.0.1:8000" MyNamespace.MyFilterClass
或
Filter.exe "127.0.0.1:8000" MyNamespace.MyFilterClass "dictionary=en-gb;cutoff=0.5"
当然,您可以使用helper类将配置字符串转换为过滤器可以使用的内容(如字典(。
当网络客户端从过滤器获得FilterResult
时,它可以相应地将数据传递回服务器/行动。
我还建议阅读一下依赖注入/控制反转和Unity。它使可插拔体系结构变得非常简单。不需要手动实例化所有内容并跟踪具体实例,只需执行以下操作即可。。。
container.Resolve<IFilter>(filterType);
容器将确保为线程/上下文获得适当的实例。
希望对有所帮助