在列表中创建类实例

时间:2014-03-16 02:21:47

标签: c# list class logging foreach

我想要完成的是:

类Logger应该将LogMedia的集合声明为成员变量,并且只需要声明一个函数:void LogException( Exception ex )。在这个函数中,你应该循环遍历所有LogMedia实例,并调用每个实例中定义的虚函数。

我无法理解的是如何实现遍历所有这些实例的循环。或者更确切地说,我如何创建这些实例?

记录器类

public class Logger
    {
       static List<LogMedia> m_loggers = new List<LogMedia>();

         **//Should I create som instances here?**
        public static void LogException(Exception ex)
        {
            foreach(var i in m_loggers)
            {
                i.LogMessage(ex.Message + Environment.NewLine);
            }
        }

        }
    }

LogMediaClass * :然后我创建了类logmedia和其他三个类,其中&#34;每个派生类应该在LogMedia类中覆盖此函数。如何创建这三个类的实例,以便我可以循环遍历它们,如Logger?*

所示
public class LogMedia
    {
        public virtual void LogMessage(string Message) { } //virtual function that doesen't do anything

    }
    public class OutputWindowLogMedia : LogMedia
    {
        public override void LogMessage(string Message)
        {
            System.Diagnostics.Debug.WriteLine(Message);
        }
    }
    class TextFileLogMedia : LogMedia
    {
        public override void LogMessage(string Message)
        {
            StreamWriter writer = new StreamWriter("C:\\Temp\\xxx\\xxxx.txt");
            writer.WriteLine(Message + " the error occured at: ");
            writer.Close();
        }
    }
    class EmailLogMedia : LogMedia
    {
        public override void LogMessage(string Message)
        {


            const string senderID = "xxx@gmail.com"; // use sender's email id here..
            const string toAddress = "xxx@some.com";
            const string senderPassword = "xxxx"; // sender password here...
            try
            {
                SmtpClient smtp = new SmtpClient
                {
                    Host = "smtp.gmail.com", // smtp server address here...
                    Port = 587,
                    EnableSsl = true,
                    DeliveryMethod = SmtpDeliveryMethod.Network,
                    Credentials = new System.Net.NetworkCredential(senderID, senderPassword),
                    Timeout = 30000,
                };
                MailMessage message = new MailMessage(senderID, toAddress, "erroe", "error");
                smtp.Send(message);
            }
            catch (Exception ex)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine("Error sending mail:" + ex.Message);
                Console.ResetColor();
            }

        }
    }

3 个答案:

答案 0 :(得分:1)

直接的方法:

public Logger()
{
    loggers.Add(new OutputWindowLogMedia ());
    loggers.Add(new TextFileLogMedia ());
    loggers.Add(new EmailLogMedia ());
}

如果你想要更加可扩展的东西,请查看MEF,或者只使用配置驱动的log4net。

答案 1 :(得分:1)

请在静态构造函数中初始化。

在那里添加所有记录器。将确保每当调用LogException()时填充列表,看到该函数是静态的。

同样只是一个想法,确实将基础LogMedia设为abstract或有利地设为interface

现在也存在副作用 - 无论何时在将来某个时间添加新的LogMedia,都必须在静态构造函数中添加Add调用。

这可能会导致维护中的大型项目出现错误,因此要避免这种情况,请在静态构造函数中添加InitializeAllLoggers()方法,并将以下代码放入其中。

foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies().ToList())
{
    foreach (Type classType in assembly.GetTypes())
    {
         if (classType.IsClass
                    && !classType.IsAbstract
                    && classType.IsSubclassOf(typeof(LogMedia)))                     
         {
              m_loggers.Add(Activator.CreateInstance(classType) as LogMedia);
         }
    }
}

这将确保无论何时创建新类型的LogMedia,它都会自动添加到记录器列表中。

答案 2 :(得分:0)

常见的方法是:

  1. 向Logger类添加注册和取消注册静态方法。这些方法只是将成员添加/删除到m_loggers列表。
  2. 您的代码使用这些方法注册/取消注册记录器。