一个简单的依赖倒置/依赖注入(Dependency Injection)的例子
1.
一个邮件发送程序
class MailService
{
public void SendEmail(string address, string subject, string
body)
{
var mail = new MailMessage();
mail.To.Add(address);
mail.Subject = subject;
mail.Body = body;
var client = new SmtpClient();
// Setup client with smtp server address and port here
client.Send(mail);
} }
增加一个日志功能
class MailService
{
public void SendMail(string address, string subject, string
body)
{
Console.WriteLine("Creating mail message...");
var mail = new MailMessage();
mail.To.Add(address);
mail.Subject = subject;
mail.Body = body;
var client = new SmtpClient();
// Setup client with smtp server address and port here
Console.WriteLine("Sending message...");
client.Send(mail);
Console.WriteLine("Message sent successfully.");
} }
现在MailService具有2个职责,发送邮件和记录日志。
把日志的实现细节分离出去。
class MailService
{
private ConsoleLogger logger;
public MailService()
{
logger = new ConsoleLogger();
}
public void SendMail(string address, string subject, string
body)
{
logger.Log("Creating mail message...");
var mail = new MailMessage();
mail.To.Add(address);
mail.Subject = subject;
mail.Body = body;
var client = new SmtpClient();
// Setup client with smtp server address and port here
logger.Log("Sending message...");
client.Send(mail);
logger.Log("Message sent successfully.");
} }
class ConsoleLogger
{
public void Log(string message)
{
Console.WriteLine("{0}: {1}", DateTime.Now, message);
}
}
现在可以日志功能的变更就分离到ConsoleLogger里面了。比如换成Windows Event Log方法记录日志。
4.
现在假设要根据开发环境和生产环境,分别用不同的Logger。比如开发环境用ConsoleLogger,生产环境用EventLogger。
class EventLogger
{
public void Log(string message)
{
EventLog.WriteEntry("MailService", message);
}
}
接口
interface ILogger
{
void Log(string message);
}
class ConsoleLogger:ILogger
{
public void Log(string message)
{
Console.WriteLine("{0}: {1}", DateTime.Now, message);
}
}
class EventLogger:ILogger
{
public void Log(string message)
{
EventLog.WriteEntry("MailService", message);
}
}
通过构造函数参数,MailService不依赖任何一个具体的Logger类,无论怎样对日志功能的修改,都不影响MailService。
public MailService(ILogger logger)
{
this.logger = logger;
}
MailService不再关心Logger类的创建,只负责使用日志类提供的功能。
internal class Program
{
private static void Main(string[] args)
{
var mailService = new MailService(new EventLogger());
mailService.SendMail("[email protected]", "My first DI
App", "Hello World!");
}
}