Heute habe ich diese Klasse haben:Abhängigkeitsinjektion - Logik im überladenen Konstruktor platzieren?
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);
}
}
Im Moment habe ich dies die SmtpEmailProvider initiieren können:
public class SmtpEmailProvider : IMessageProvider
{
private readonly SmtpClientWrapper _smtpClientWrapper;
public SmtpEmailProvider(SmtpClientWrapper smtpClientWrapper)
{
_smtpClientWrapper = smtpClientWrapper;
}
Um in der Lage sein, die SmtpClient zu verspotten, habe ich es so gewickelt Klasse, und legen Sie die SmtpClient Logik gibt:
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));
}
Aber ich möchte ersetzen, dass mit:
public IMessageProvider LocateProviderByName(string providerName)
{
return IoC.Resolve<IMessageProvider>(providerName);
}
Dann muss ich die Logik im Konstruktor ohne Parameter platzieren. Aber ich habe das Gefühl, dass ich im Konstruktor viel zu tun habe.
Gibt es einen anderen Weg, es zu tun?
+ 1 für neue Ideen, wie man Dinge macht. Aber sagen, dass die Logik dort ist nicht nur etwas, das mit IoC angegeben werden kann. So muss ich zum Beispiel in der Lage sein, Host/Port von einem anderen Einstellungsrepository abhängig von einigen Parametern abzurufen. Wo wäre der richtige Ort, um die Logik zu setzen? – Allrameest
Wenn Sie diese Art von Fähigkeit benötigen, würde ich einen anderen Anbieter oder eine Fabrik erstellen, die injiziert werden kann, als eine Instanz von dem, was Sie brauchen. Zum Beispiel scheint es so, als müssten Sie dem SmtpClient einen Host, Port und Credential dynamisch zuweisen. Ich würde eine SmtpClientFactory erstellen, die dann in den SmtpClientWrapper eingefügt wird. Der SmtpClientWrapper kann dann intern seine interne Instanz des SmtpClients erstellen (und bei Bedarf zwischenspeichern). Um hier Mockability zu erhalten, müssen Sie sicherstellen, dass Ihre SmtpClientFactory über virtuelle Methoden verfügt. – jrista
Ok! Eine Fabrik war eine Sache, die mir vorschwebte. Ich werde damit gehen! :) – Allrameest