Right now we use DI/IOC and when we need to pass extra parameters to a constructor we use a factory class e.g.
public class EmailSender
{
internal EmailSender(string toEmail, string subject,String body, ILogger emailLogger)
{.....}
}
public class EmailSenderFactory
{
ILogger emailLogger;
public EmailSenderFactory(ILogger emailLogger)
{
this.emailLogger = emailLogger;
}
public EmailSender Create(string toEmail, string subject, string body)
{
return new EmailSender(toEmail, subject, body, emailLogger);
}
}
Now the problem with this is that we end up creating a whole lotta factory classes, and people don't always know to use them (they sometimes new them up themselves). What are the biggest negatives of coding the class like this:
public class EmailSender
{
EmailLogger logger = IoC.Resolve<ILogger>();
internal EmailSender(string toEmail, string subject,String body)
{.....}
}
Pro: we now can use the constructor safely without needing a factory class
Con: we have to reference the Service Locator (I'm not worried about testability, its easy to use a mock container as the backing service for the container).
Is there some big stinker of a reason out there why we shouldn't do this?
edit: after a bit of thought, I twigged that by having a private constructor, and by nesting the Factory class, I could keep the implementation and factory together, and prevent people from creating classes improperly, so the question has become somewhat moot. All the points points about SL being dirty, are of course true, so the solution below keeps me happy:
public class EmailSender
{
public class Factory
{
ILogger emailLogger;
public Factory(ILogger emailLogger)
{
this.emailLogger = emailLogger;
}
public EmailSender Create(string toEmail, string subject, string body)
{
return new EmailSender(toEmail, subject, body, emailLogger);
}
}
private EmailSender(string toEmail, string subject,String body, ILogger emailLogger)
{
}
}
See Question&Answers more detail:
os