将参数从项目传递到另一个项目中的特定类

时间:2016-10-29 22:13:15

标签: c# .net

我刚开始为学校项目学习C#,但我坚持不懈。

我有一个包含2个项目的解决方案(每个项目都有一个类),如下所示:

解决方案:

  • 服务器(项目)(...)MyServerClass.cs,Program.cs
  • App(项目)(...)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,...),然后为每个不同的过滤器创建一个新进程。

我想我会坚持每个过滤器的项目!

谢谢!

1 个答案:

答案 0 :(得分:1)

有很多方法可以实现这一目标,每种方法都有自己的优点/缺点。

一些可能的解决方案:

  • 在命令行中传递值。优点:简单。缺点:只能在发布时传递一次。单向(子进程无法发回信息)。对于复杂的结构化数据,它不能很好地扩展。
  • 创建网络服务(在服务器或客户端中)。连接到它并拉/推适当的设置。优点:灵活,持续,可能是双向的,具有某种形式的轮询,并且如果客户端/服务器位于不同的主机上,则可以正常工作。缺点:稍微复杂一点,需要一个应用程序能够找到另一个应用程序的Web地址,这个地址在本地很简单,并且更多地涉及网络。
  • 通过内存映射文件使用共享内存。此方法允许多个进程访问同一块内存。一个进程可以写入所需的数据,其他进程可以读取它。优点:高效,双向,可以通过重新启动磁盘备份以保持状态。缺点:需要指针并了解它们的工作原理。需要对数据进行更多操作才能执行读/写操作。

还有几十种方法。如果不详细了解您的情况,很难推荐一个在另一个上面。

编辑Re:更新了要求

好的,命令行绝对是个不错的选择。快速绕道一些建筑......

没有理由你不能用一个项目来做这件事。

首先,使用界面确保所有过滤器都可以互换。像这样......

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"

当然,您可以使用帮助程序类将配置字符串转换为您的过滤器可以使用的内容(如字典)。

当网络客户端从过滤器返回FilterResult时,它可以将数据传回服务器/行为。

我还建议关于控制和Unity的依赖注入/反转的a little reading。它使可插拔架构变得更加简单。您可以执行类似......

之类的操作,而不是手动实例化所有内容并跟踪具体实例
container.Resolve<IFilter>(filterType);

容器将确保为线程/上下文获取适当的实例。

希望有所帮助