我想要完成的是:
类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();
}
}
}
答案 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)
常见的方法是: