C# 检查是否从Windows窗体应用程序调用代码

C# 检查是否从Windows窗体应用程序调用代码,c#,winforms,web-services,C#,Winforms,Web Services,我有一个类库,可以从Web服务、服务或windows窗体应用程序调用 对于windows窗体应用程序,我想为Web服务显示一个yes/no消息框,我只想假设该服务为yes 我知道我可以重构代码以使用抽象层,例如 var provider = new MessageBoxProvider(); // Or other implementation var result = provider.QueryResult(...); 除此之外: 是否有更好的方法检查是否从windows应用程序调用代码?

我有一个类库,可以从Web服务、服务或windows窗体应用程序调用

对于windows窗体应用程序,我想为Web服务显示一个yes/no消息框,我只想假设该服务为yes

我知道我可以重构代码以使用抽象层,例如

var provider = new MessageBoxProvider(); // Or other implementation
var result = provider.QueryResult(...);
除此之外:

是否有更好的方法检查是否从windows应用程序调用代码?目前我正在做

System.Windows.Forms.Application.OpenForms.Count > 0

我更愿意使用依赖注入,在这种情况下,您可以将带有方法的接口传递给类,这样它也可以在单元测试中进行测试,并且可以从Windows窗体应用程序进行设置,而不依赖于该类中的Windows窗体内容。我想这就像你的抽象层

public interface IMessageHandler
{
    void SendMessage(string message);
}

public class WindowsFormsMessageHandler : IMessageHandler
{
    public void SendMessage(string message)
    {
        System.Windows.Forms.MessageBox.Show(message);
    }
}

public class OuterClass
{
    private IMessageHandler _handler;

    public OuterClass(IMessageHandler handler)
    {
        if (handler == null)
            throw new ArgumentNullException("handler");

        _handler = handler;
    }

    public void DoSomething()
    {
        _handler.SendMessage("Hello");
    }    
}


通过这样做,您只需根据您来自何处的实现更改行为,而不必依赖可能不可靠的检查。

您只需向类库传递bool,例如:

new ClassLibrary(true);
当它是WinForms应用程序时

然后让构造函数与下面类似

ClassLibrary(bool calledFromWinforms)

我知道这不是最好的代码,但它使事情变得简单,不会使事情过于复杂。

我使用
System.Environment.UserInteractive
进行这种检查

如果我没有错,那么对于windows应用程序,返回true;对于windows服务、web应用程序和web服务,返回false。(控制台应用程序呢?我应该检查一下)


我同意您应该以不同的方式来解决它,正如其他人所指出的那样

我的方法是向类中添加一个属性,该属性在实例化时设置自身并存储其运行的环境类型。之后可以使用该属性来标识从何处调用它

我不确定您的库中是否需要任何ui逻辑,是否可以重构它以仅返回消息并让调用方处理它?这看起来像是一个XY问题,并且存在大量的解决方案来防止您首先需要将库代码绑定到特定的ui框架。除了抽象层之外,您还可以创建一个调用应用程序可以订阅的事件或回调。另请参阅,where all current answers也存在,并提供有关潜在缺陷等的更多信息。这个问题的答案是什么?依赖注入在哪里发挥作用?不要在类中进行(不可靠的)检测,而是提供一个将消息发送到的接口。我用一个代码示例进行了更新!这可以防止您将windows窗体内容拖到类中,并防止它依赖于将来可能更改的检查。对于控制台应用程序,它会返回true,我忘了这一点,这听起来是一个好方法。tks@TheLethalCoder。仔细想想,它不应该取决于应用程序的类型,而是取决于它在操作系统中的运行方式。如果从命令提示符UserInteractive启动控制台应用程序是正确的,但我怀疑如果作为窗口计划任务启动它是错误的。我认为这会使它更复杂,这意味着库仍然需要引用winforms类,调用者也不清楚,如果从winforms调用或不从winforms调用,为什么会有不同。@Sayse就像我说的,不是最好的代码,而是一种“解决”问题的方法,如果你想让它更清楚,可以随时将其改为
bool showMessageBox
当然,但我认为它解决不了问题,它只是把它推到别的地方
ClassLibrary(bool calledFromWinforms)