I'm having some trouble conceptualizing what I'm supposed to do to facilitate communication between my class library and programs that use it -- in this case, a Windows Forms app:
// 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();
}
}
Since there is nothing listening to the console in a winforms app, calls to log() show nothing. Is there a way to dynamically overwrite the Foo.Log method, or possibly assign a method with that signature to the Foo object that is more suitable for a forms app at runtime?
Thank you!
Declare a logger interface and inject a concrete logger into the library class
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...");
}
}
Use it like this
var foo = new Foo(new ConsoleLogger());
var foo = new Foo(new FileLogger());
var foo = new Foo(new MsgBoxLogger());
Where all these loggers implement the interface.
public class ConsoleLogger : ILogger
{
public void Log(string message)
{
Console.WriteLine(message);
}
}
UPDATE
As Mike Panter has pointed out already, you can use a delegate
public class Foo
{
private Action<string> _writeLog;
public Foo (Action<string> writeLog)
{
_writeLog = writeLog;
}
public void DoWork ()
{
_writeLog("Working...");
}
}
you can call it like this
var foo = new Foo(s => Console.WriteLine(s));
Advantages of the delegate injection
See Jon Skeets article The Beauty of Closures for variable capturing.
Advantages of the interface injection
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With