如何在启动时将事件附加到控制台应用

时间:2014-07-30 11:51:10

标签: c# reflection

我有应用程序需要添加其他隐藏日志记录。

我已经把原型放进去了。

using System;
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Start");

        new DummyTest().Report();

        Console.WriteLine("End");
        Console.ReadKey();
    }
}
public class DummyTest
{
    public void Report()
    {
        var reporter = new Reporter();
        Console.WriteLine("Reporting");
        for (var i =0; i < 155; i++)
        {
            reporter.Process(i);
        }
        Console.WriteLine("Reporting end");
    }
}
public class Reporter
{
    // attach behavior here
    public void Process(int requestId)
    {
        Console.WriteLine("Processing request: {0}" , requestId);
        System.Threading.Thread.Sleep(100);
    }
}

现在我有了包含

的新项目logger.dll
using System;

namespace logger
{
    public class Log
    {
        public Log()
        {
            Console.WriteLine("Line executed");
        }
    }
}

现在我想每次执行Main时执行此方法。但是,除了仅通过引用dll之外,不能以任何其他方式引用它。


=更新=

我不介意参考那个dll。但是在主代码中我不能对Log有任何引用。我想过使用反射来使这个工作。我试图首先解决的问题是如何将其附加到执行中。

  • 为什么我不能从main调用记录器?

  • 这应该是报告班级的使用情况,监控使用情况,以便报告瓶颈上的表现。

2 个答案:

答案 0 :(得分:0)

你可以这样做:

void Main()
{
    System.Console.SetOut(new CustomTextWriter());

    Console.WriteLine("test");
}

public class CustomTextWriter : TextWriter
{
    private TextWriter _consoleOut = null;
    private Log _logger = null;

    public CustomTextWriter()
    {
        _consoleOut = System.Console.Out;
        _logger = new Log();
    }

    public override void Write(char[] buffer, int index, int count)
    {
        this.Write(new String(buffer, index, count));
    }

    public override void Write(string value)
    {
        _consoleOut.Write(value);
        _logger.Write(value);
    }

    public override void WriteLine(string value)
    {
        _consoleOut.WriteLine(value);
        _logger.WriteLine(value);
    }

    public override Encoding Encoding
    {
        get { return System.Text.Encoding.Default; }
    }
}

我不确定你是否想在没有实际调用Console.WriteLine()的情况下进行记录(如果是,你需要查看Interception)但是如果没关系那么这应该可以帮助你完成。

希望这有帮助。

答案 1 :(得分:-1)

你可以用这样的反射来做到这一点:

// load the assembly
Assembly LogDll = Assembly.LoadFile(@"Log.dll");

// get the type of the Log class
Type LogType = LogDll.GetType("logger.Log");

// get instance of the Log class
object LogInstance = Activator.CreateInstance(LogType);

// invoke class member "Log()"
LogType.InvokeMember("Log",
                        BindingFlags.InvokeMethod | 
                        BindingFlags.Instance | 
                        BindingFlags.Public,
                        null, 
                        LogInstance, 
                        null);

虽然我不确定是否已通过创建实例调用构造函数“Log()”。您应该将实际的日志方法移出构造函数。要传递参数,可以使用InvokeMember的最后一个参数,它是Object类型的数组。