所以我们有一个类需要输出操作的结果。现在这与电子邮件紧密耦合,但是依赖注入,我认为我可以添加更多的持久性选项,例如。保存到磁盘。
问题是保存到磁盘需要一条路径,同时“保存”#39;因为电子邮件需要其他详细信息(从,到等)。
这是通过依赖注入可以实现的吗?或者我做错了什么?检查下面的代码和我的评论,以便更好地理解我的问题...
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;
}
}
答案 0 :(得分:2)
你需要做的就是通过足够的&#39;有关持久化类消息的上下文信息。然而,传递特定于电子邮件的信息(如从和到)会导致您将持久性机制的实现细节泄露到OriginalClass
,这不是您应该要的。执行此操作将导致您每次添加新OriginalClass
实施时都必须更改IPersistence
。这显然很糟糕(它会打破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
。
答案 1 :(得分:0)
这样的东西应该可以工作,因为现在IEmailManager也可以通过DI框架,所有你需要做的就是引导EmailManager构建。
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;
}
}