I have a factory class that creates a couple of different types of class. The factory is registered with the container. What is the recommended way of creating the classes insid
While this question is subjective (the answer will be as well), I would say that your first approach is the appropriate one.
When you utilize Dependency Injection
you have to understand what is an actual dependency. In this case, WorkerA
and WorkerB
are not really dependencies, but clearly Dependency1
and Dependency2
are dependencies. In a real-world scenario, I have used this pattern in my Micrsoft Prism applications.
Hopefully an example of my application will give you a better understanding of the pattern to use. I utilized the ILoggerFacade
dependency. I had some view-models that resided in a separate assembly (the factory resided in that assembly as well). My individual IPlayerViewModel
s were not dependencies (which is why I didn't go the second route).
ShellViewModel.cs:
[Export]
public sealed class ShellViewModel : NotificationObject
{
public ShellViewModel()
{
Players = new ObservableCollection();
// Get the list of player models
// from the database (ICollection)
var players = GetCollectionOfPlayerModels();
foreach (var player in players)
{
var vm = PlayerViewModelFactory.Create(player);
Players.Add(vm);
}
}
[Import]
private IPlayerViewModelFactory PlayerViewModelFactory { get; set; }
public ObservableCollection Players { get; private set; }
}
IPlayerViewModelFactory.cs
public interface IPlayerViewModelFactory
{
IPlayerViewModel Create(IPlayer player);
}
IPlayer.cs
public interface IPlayer
{
// Sport Enum
Sport Sport { get; set; }
}
Separate assembly / PlayerViewModelFactory.cs
[Export]
public sealed class PlayerViewModelFactory : IPlayerViewModelFactory
{
[Import]
private ILoggerFacade Logger { get; set; }
public IPlayerViewModel Create(IPlayer player)
{
switch (player.Sport)
{
case Sport.Basketball:
return new BasketballViewModel(Logger, player);
case Sport.Football:
return new FootballViewModel(Logger, player);
// etc...
default:
throw new ArgumentOutOfRangeException("player");
}
}
}