Внедрить несколько сервисов в конструктор VS внедрить один ServiceFactory в конструктор - PullRequest
0 голосов
/ 21 ноября 2018

Я хотел бы получить совет о том, каков наилучший подход между этими двумя решениями:

с использованием единицы я регистрирую N интерфейсов / классов служб

internal class Configurator
    {
        private static IUnityContainer container = new UnityContainer();

        internal static void Configure()
        {
            container.RegisterType<ICustomerService, CustomerService>();
            container.RegisterType<IPhoneService, PhoneService>();
            container.RegisterType<IUserService, UserService>();
            ...
        }

        internal static T Resolve<T>()
        {
            return container.Resolve<T>();
        }
    }

Где все интерфейсы реализуют IService

public interface ICustomerService : IService
public interface IPhoneService: IService
public interface IUserService: IService

Я также создал класс ServiceFactory

public class ServiceFactory : IServiceFactory
    {
        public T GetService<T>() where T : IService
        {
            return Configurator.Resolve<T>();
        }
    }

, теперь я сомневаюсь:

РЕШЕНИЕ 1:

public class TestViewModel
{
    private ICustomerService _customerService;

    private IPhoneService _phoneService;

    private IUserService _userService;

    public TestViewModel(ICustomerService customerService, IPhoneService phoneService, IUserService userService)
    {
        _customerService = customerService;
        _phoneService = phoneService;
        _userService = userService;
    }

РЕШЕНИЕ 2:

public class TestViewModel
{
    private IServiceFactory _serviceFactory;

    private IUserService _userService;
    public IUserService UserService
    {
        get
        {
            if(_userService == null)
                _userService = _serviceFactory.GetService<IUserService>();
            return _userService;
        }
    }

    public MainWindowViewModel(IServiceFactory serviceFactory)
    {
        _serviceFactory = serviceFactory;
    }

Лично я предпочитаю решение 2, потому что

1) если мне нужно внедрить много услуг в одном конструкторе, я могу внедрить только фабрику

2)сервисы инициализируются только по запросу (в решении 1 они все инициализируются в конструкторах, даже если пользователь никогда не будет вызывать / использовать их все)

Согласны ли вы с тем, что решение 2 лучше? Есть ли противопоказания? Iхочу услышать ваше мнение ...

1 Ответ

0 голосов
/ 21 ноября 2018

Этот класс ServiceFactory в основном действует как Сервисный локатор , который считается антишаблоном.Причина в том, что таким образом у вашего сервиса гораздо больше энергии, чем нужно.Объявляя ваши зависимости в конструкторе, у вас есть строгие рекомендации относительно того, что вам понадобится и что вы будете использовать в своем классе.

Если у вас слишком много параметров конструктора, это может быть запахом кода, указывающим на то, что ваш класс, вероятно, делает больше, чем должен, и может нарушать Принцип единой ответственности .В этом случае вам следует подумать о том, чтобы реорганизовать этот класс в меньшие подклассы, каждый из которых выполняет более мелкие задачи.

Мой вопрос в том, что первое решение лучше

...