依赖注入的初学者
本文关键字:初学者 注入 依赖 | 更新日期: 2023-09-27 18:30:12
所以我们有一个类,它确实需要输出操作的结果。现在这与电子邮件紧密耦合,但是通过依赖注入,我认为我可以添加更多的持久性选项,例如。保存到磁盘。
问题是保存到磁盘需要路径,而"保存"为电子邮件需要其他详细信息(发件人、收件人等(。
这是可以通过依赖注入来实现的吗?还是我做错了整件事?检查下面的代码和我的评论,以更好地了解我的问题......
public class OriginalClass
{
IPersistence _persistence;
public OriginalClass(IPersistence persistence)
{
this._persistence = persistence;
}
public void DoSomething()
{
// I have all the information needed to send an email / save to disk. But how do I supply it?
this._persistence.Put("Message to save");
}
}
public interface IPersistence
{
bool Put<T>(T data);
}
public class EmailPersistence : IPersistence
{
public bool Put<T>(T data)
{
// How am I going to get the FROM and TO details?
return EmailManager.Send("FROM", "TO", data.ToString());
};
}
public class DiskPersistence : IPersistence
{
public bool Put<T>(T data)
{
// How am I going to get the SAVE PATH details?
// I just used a new initialization. So I'm probably doing this wrong as well...
new System.IO.StreamWriter("SAVE PATH").Write(data.ToString());
return true;
}
}
您需要做的是将有关消息的"恰到好处"的上下文信息传递给持久性类。 传递特定于电子邮件的信息(例如 from 和 to(会导致您将持久性机制的实现细节泄漏到 OriginalClass
中,这不是您想要的。这样做会导致每次添加新的IPersistence
实现时都必须更改OriginalClass
。这显然是不好的(它破坏了OCP和DIP(。
因此,究竟要提供什么只有您可以确定,但它可能是允许实现检索运行所需信息的标识符。这可以类似于为其写入消息的联系人或组织的 ID。这样,您只需传入消息和此 ID,实现就可以使用此 ID 来查询数据库以获取所需的任何内容。
但是,如果这些值在应用程序运行时期间未更改,则解决方案将完全不同。在这种情况下,您应该简单地使用构造函数注入:
public class EmailPersistence : IPersistence {
private readonly MailAddress from;
private readonly MailAddress to;
public EmailPersistence(MailAddress from, MailAddress to) {
this.from = from;
this.to = to;
}
public bool Put(string data) {
// How am I going to get the FROM and TO details?
return EmailManager.Send(this.from, this.to, data.ToString());
};
}
由于设置不会更改,因此您可以在应用程序启动期间从配置文件(或从任何地方(加载它们,并且可以使用这些固定配置值简单地创建新EmailPersistence
。
这样的东西应该可以工作,因为现在IEmailManager也可以通过DI框架,您需要做的就是引导EmailManager Construction。
public class OriginalClass
{
IPersistence _persistence;
public OriginalClass(IPersistence persistence)
{
this._persistence = persistence;
}
public void DoSomething()
{
// I have all the information needed to send an email / save to disk. But how do I supply it?
this._persistence.Put("Message to save");
}
}
public interface IPersistence
{
bool Put<T>(T data);
}
public class EmailPersistence : IPersistence
{
private readonly IEmailManager _manager;
public EmailPersistence(IEmailManager manager)
{
_manager = manager;
}
public bool Put<T>(T data)
{
// How am I going to get the FROM and TO details?
return _manager.Send();
}
}
public class EmailManager : IEmailManager
{
public string From { get; set; }
public string To { get; set; }
public bool Send()
{
throw new NotImplementedException();
}
public dynamic Data { get; set; }
}
public interface IEmailManager
{
string From { get; set; }
string To { get; set; }
dynamic Data { get; set; }
bool Send();
}
public class DiskPersistence : IPersistence
{
public string Path { get; set; }
public DiskPersistence(string path)
{
Path = path;
}
public bool Put<T>(T data)
{
// How am I going to get the SAVE PATH details?
// I just used a new initialization. So I'm probably doing this wrong as well...
new System.IO.StreamWriter(Path).Write(data.ToString());
return true;
}
}