我想要完成的是:
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和其他三个类,其中“每个派生类随后应在LogMedia类中重写此函数。如何创建这三个类的实例,以便可以遍历它们,如图所示在记录仪中?*
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 = "[email protected]"; // use sender's email id here..
const string toAddress = "[email protected]";
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();
}
}
}
最佳答案
请在静态构造函数中初始化。
在其中添加所有记录器。可以确保每当调用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
类型时,它都会自动添加到记录器列表中。