When dealing with objects that require data known only at runtime, such as a username and password, where should object instantiation happen: by using new, in a factory, or in a DI container?
For example, I could just new an object once I have the data:
UserCredentials creds =
new UserCredentials(dialog.getUsername(), dialog.getPassword());
Or, I could use a factory:
UserCredentials creds =
CredentialsFactory.create(dialog.getUsername(), dialog.getPassword());
Or, I could use a provider within a DI container (which in this case would essentially be a parameter-driven factory). [Sample code omitted.]
It seems both wrong to use the DI container for something so simple yet it also seems wrong not to use it to its fullest.
As always, it depends, but as a general rule, a static factory like your second option is only rarely a good idea.
newing up a UserCredential object seems like a fair choice because the UserCredentials class looks like a self-contained, concrete class that can be fully instantiated with all its invariants from the username and password.In other cases, the type you would like to create may represent an abstraction in itself. If this is the case, you can’t use the
newkeyword, but must use an Abstract Factory instead.Using an Abstract Factory is often very valuable because it allows you to compose an instance from a combination of run-time values and other dependencies. See here for more information.
Using an Abstract Factory also helps with unit testing because you can simply test that the return value or end state or whatever you care about is related to the output of the Abstract Factory – for which you can easily supply a Test Double because it is… abstract.