Simple Injector:Factory classes that need to create classes with dependencies

前端 未结 4 1866
灰色年华
灰色年华 2021-02-14 15:45

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

4条回答
  •  后悔当初
    2021-02-14 16:29

    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 IPlayerViewModels 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");
            }
        }
    }
    

提交回复
热议问题