Aujourd'hui, j'ai cette classe:Injection de dépendances - Place la logique dans le constructeur surchargé?
public class SmtpEmailProvider : IMessageProvider
{
private readonly SmtpClientWrapper _smtpClientWrapper;
public SmtpEmailProvider(SmtpClientWrapper smtpClientWrapper)
{
_smtpClientWrapper = smtpClientWrapper;
}
Pour pouvoir se moquer de la SmtpClient, je l'ai enveloppé comme ceci:
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);
}
}
En ce moment, je peux le faire pour lancer le SmtpEmailProvider classe, et placez-le là logique 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));
}
Mais je veux le remplacer par:
public IMessageProvider LocateProviderByName(string providerName)
{
return IoC.Resolve<IMessageProvider>(providerName);
}
Ensuite, j'ai besoin de placer la logique dans le constructeur sans paramètres. Mais j'ai l'impression que je fais beaucoup dans le contructor alors.
Existe-t-il un autre moyen de le faire?
+ 1 pour me donner de nouvelles idées de comment faire les choses. Mais dites que la logique n'est pas seulement quelque chose qui peut être spécifié avec IoC. Comme ça, je dois par exemple être capable de récupérer un hôte/port à partir d'un autre référentiel de paramètres en fonction de certains paramètres. Où serait le bon endroit pour mettre la logique? – Allrameest
Si vous avez besoin de ce type de fonctionnalités, je créerais un autre fournisseur ou une autre usine pouvant être injectée plutôt qu'une instance de ce dont vous avez besoin. Par exemple, il semble que vous deviez assigner dynamiquement un hôte, un port et des informations d'identification à SmtpClient. Je voudrais créer un SmtpClientFactory qui est ensuite injecté dans le SmtpClientWrapper. Le SmtpClientWrapper peut alors créer son instance interne du SmtpClient en interne (et la mettre en cache si nécessaire). La chose clé ici, pour maintenir la similitude, est de s'assurer que votre SmtpClientFactory a des méthodes virtuelles. – jrista
Ok! Une usine était une chose que j'avais en tête. Je vais aller avec ça! :) – Allrameest