Как внедрить новый экземпляр во время выполнения в Prism? - PullRequest
0 голосов
/ 20 сентября 2019

Я использую Prism 7.1 для приложения WPF.Я пытался использовать встроенный IOC (Unity), но я не знаю, как я могу разрешить новый экземпляр во время выполнения, возможно, из метода или из containerProvider.Но кажется, что IContainerProvider недоступен для инъекций в моей модели представления.У меня есть какой-либо вариант?

Я хочу сделать это, чтобы перезагрузить контекст моей базы данных.Мне сказали, что создание нового контекста является самым простым среди других.

    public class ProjectViewModel : BindableBase
    {
        private UnitOfWork unitOfWork;
        private IContainerProvider containerProvider;
        private IEventAggregator eventAggregator;
        #region Constructor
        public ProjectViewModel(UnitOfWork unitOfWork, IContainerProvider cp, IEventAggregator ea)
        {
            this.unitOfWork = unitOfWork;
            containerProvider = cp;
            eventAggregator = ea;
            eventAggregator.GetEvent<SendReloadDataEvents>().Subscribe(Reload);
            Reload();
        }
        #endregion

        private void Reload()
        {
            this.unitOfWork = containerProvider.Resolve<UnitOfWork>();
            Projects = new ObservableCollection<Projects>(unitOfWork.ProjectRepo.GetAll());
            Customers = new ObservableCollection<Customers>(unitOfWork.CustomerRepo.Find(x => x.Projects.Count > 0));
            SelectedProjectType = null;
        }
//Other logic continues
}

1 Ответ

0 голосов
/ 20 сентября 2019

Инъекция контейнера - это анти-шаблон, поэтому мы постараемся избежать этого и вместо этого внедрить фабрику.Фактически, IContainerProvider и IContainerRegistry не зарегистрированы сами по этой причине, чтобы сделать невозможным их инъекцию.

Хотя фабрика проста:

public class ProjectViewModel : BindableBase
{
    private UnitOfWork unitOfWork;
    private Func<UnitOfWork> unitOfWorkFactory;
    private IEventAggregator eventAggregator;
    #region Constructor
    public ProjectViewModel(Func<UnitOfWork> unitOfWorkFactory, IEventAggregator ea) // no need to inject a unit of work
    {
        _unitOfWorkFactory = unitOfWorkFactory;
        eventAggregator = ea;
        ea.GetEvent<SendReloadDataEvents>().Subscribe(Reload); // prefer the parameter
        Reload();
    }
    #endregion

    private void Reload()
    {
        this.unitOfWork = _unitOfWorkFactory(); // create a new one here (the container does the work but is hidden)
        Projects = new ObservableCollection<Projects>(unitOfWork.ProjectRepo.GetAll()); // I'd rather update the existing collection
        Customers = new ObservableCollection<Customers>(unitOfWork.CustomerRepo.Find(x => x.Projects.Count > 0)); // same here, or probably, it could just be IEnumerable
        SelectedProjectType = null;
    }
//Other logic continues
}

Обратите внимание, чтоЭта фабрика Func<> подходит только для самых простых случаев.Если вам нужны параметры, передаваемые в конструктор продукта, вы должны сами его кодировать, как описано в этом ответе .Также обратите внимание на то, что контейнер никогда нигде не отображается (кроме случаев, когда он настроен), что делает ваш код зависимым от контейнера просто ненужным и сделает тесты более уродливыми.

...