如何从类库中进行通信

Dan*_*abo 2 .net c# class-library winforms

我在构建我应该做的事情上有些麻烦,以促进我的类库和使用它的程序之间的通信 - 在这种情况下,Windows Forms应用程序:

// Class in library
class Foo()
{
    public Foo(){}

    public void DoWork()
    {
        log("Working...");
    }

    private void log( string s )
    {
        Console.Writeline(s);
    }

}

// Forms App
class Form1()
{
    public Form1()
    {
        Foo MyFoo = new Foo();
        MyFoo.DoWork();
    }
}
Run Code Online (Sandbox Code Playgroud)

由于在winforms应用程序中没有任何内容监听控制台,因此对log()的调用不会显示任何内容.有没有办法动态覆盖Foo.Log方法,或者可能将具有该签名的方法分配给更适合运行时表单应用程序的Foo对象?

谢谢!

Oli*_*bes 9

声明一个记录器接口并将具体的记录器注入库类

public interface ILogger
{
    void Log(string message);
}

public class Foo
{
    private ILogger _logger;

    public Foo (ILogger logger)
    {
        _logger = logger;
    }

    public void DoWork ()
    {
        _logger.Log("Working...");
    }
}
Run Code Online (Sandbox Code Playgroud)

像这样使用它

var foo = new Foo(new ConsoleLogger());
var foo = new Foo(new FileLogger());
var foo = new Foo(new MsgBoxLogger());
Run Code Online (Sandbox Code Playgroud)

所有这些记录器都实现了接口.

public class ConsoleLogger : ILogger
{
    public void Log(string message)
    {
        Console.WriteLine(message);
    }
}
Run Code Online (Sandbox Code Playgroud)

UPDATE

正如Mike Panter已经指出的那样,你可以使用一个代表

public class Foo
{
    private Action<string> _writeLog;

    public Foo (Action<string> writeLog)
    {
        _writeLog = writeLog;
    }

    public void DoWork ()
    {
        _writeLog("Working...");
    }
}
Run Code Online (Sandbox Code Playgroud)

你可以这样称呼它

var foo = new Foo(s => Console.WriteLine(s));
Run Code Online (Sandbox Code Playgroud)

代表注入的优点

  • 很容易申报
  • 使用非常简单
  • 您可以通过变量捕获传递其他参数.

        请参阅Jon Skeets的文章The Beauty of Closures for variables capture.

接口注入的优点

  • 您可以通过其构造函数轻松地将参数传递给记录器,就像FileLogger的文件名一样.由于构造函数不是接口的一部分,因此不同的记录器可以具有不同的构造函数参数.
  • 您可以使用单元测试轻松测试它,使用匿名lambda表达式无法做到这一点,因为无法从单元测试中访问它们.
  • 您可以在库类的单元测试中使用模拟记录器.
  • 您可以通过从现有记录器派生来创建新的专用记录器.
  • 您可以在记录器中声明私有帮助器方法.

  • 注意:您可以在Visual Studio的Ouput窗口中看到WinForms程序的控制台输出。 (2认同)