今天我上了这堂课:
public class SmtpEmailProvider : IMessageProvider
{
private readonly SmtpClientWrapper _smtpClientWrapper;
public SmtpEmailProvider(SmtpClientWrapper smtpClientWrapper)
{
_smtpClientWrapper = smtpClientWrapper;
}
为了能够模拟SmtpClient,我把它包装成这样:
public class SmtpClientWrapper
{
private readonly SmtpClient _smtpClient;
public SmtpClientWrapper(SmtpClient smtpClient)
{
_smtpClient = smtpClient;
}
public virtual void Send(MailMessage msg)
{
if (_smtpClient == null) throw new InvalidOperationException("SmtpClient must be passed to the constructor before calling Send.");
_smtpClient.Send(msg);
}
}
现在我可以这样做来启动SmtpEmailProvider类,并将SmtpClient逻辑放在那里:
public IMessageProvider LocateProviderByName(string providerName)
{
var client = new SmtpClient
{
Host = "127.0.0.1",
Port = 25
};
client.Credentials = new NetworkCredential("...", "...");
return new SmtpEmailProvider(new SmtpClientWrapper(client));
}
但我想用以下内容代替:
public IMessageProvider LocateProviderByName(string providerName)
{
return IoC.Resolve<IMessageProvider>(providerName);
}
然后我需要将逻辑放在没有参数的构造函数中。但我觉得我在构造函数中做的很多。
还有其他办法吗?
答案 0 :(得分:2)
我对你想要完成的事情感到有点困惑。如果我假设您需要提供Smtp电子邮件,并且您正在使用IoC,那么您应该使用IoC框架创建并连接整个对象图。通过这种方式,我的意思是你要配置你的IoC框架来创建SmtpClient,然后用它创建SmtpClientWrapper,最后用它创建SmtpEmailProvider。您不需要在SmtpEmailProvider构造函数中放置任何依赖关系创建逻辑。
根据您提供的代码,以下是Castle Windsor的示例:
<configuration>
<component id="smtpClient" type="System.Net.Mail.SmtpClient, System">
<parameters>
<Host>127.0.0.1</Host>
<Port>25</Port>
</parameters>
</component>
<component id="smtpClientWrapper" type="Naespace.SmtpClientWrapper, Assembly">
<parameters>
<smtpClient>${smtpClient}</smtpClient>
</parameters>
</component>
<component id="smtpProvider" service="Namespace.IMessageProvider, Assembly" type="Namespace.SmtpEmailProvider, Assembly">
<parameters>
<smtpClientWrapper>${smtpClientWrapper}</smtpClientWrapper>
</parameters>
</component>
</configuration>
使用上面的Windsor配置,您可以像这样简单地创建IMessageProvider:
public IMessageProvider LocateProviderByName(string providerName)
{
return IoC.Resolve<IMessageProvider>(providerName);
}
var messageProvider = LocateProviderByName("smtpProvider");
这里的关键点是使用IoC容器:依赖项创建和管理系统,可以而且应该为您创建完整的对象图。这缓解了构造函数中过多依赖管理逻辑的问题。