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

本文关键字:控制台 应用程序 事件 启动 | 更新日期: 2023-09-27 18:15:31

我有一个应用程序,我需要添加额外的隐藏日志记录。

I have put prototype in way.

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。但在主代码我不能有任何参考日志。我想过用反射来完成这个作品。我首先要解决的问题是如何将其附加到执行中。

  • 为什么我不能从main调用logger ?

  • 这应该报告类的使用情况,监控使用情况,以便报告瓶颈上的性能。

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

你可以这样做:

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),但如果可以,那么这应该可以让你通过。

你可以这样做:

// 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类型的数组。