MVVM-Light: куда поместить вызов WCF во ViewModel - PullRequest
2 голосов
/ 31 июля 2011

Я создаю приложение WP7, которое получает все свои данные через службы WCF.Я хочу реализовать в нем MVVM-Light, но в уроках, которые я сделал, я вижу, что в ViewModelLocator он хочет создать статический экземпляр всех моих ViewModel при запуске приложения.Моя проблема в том, что в моих конструкторах для моей виртуальной машины я делаю вызовы WCF, и результаты, конечно же, возвращаются в обратном вызове.Именно в обратном вызове я присваиваю результаты моей наблюдаемой коллекции, которую видят мои представления.Это прекрасно работает, когда не используется MVVM-Light, но если я его реализую, у меня не будет этих вызовов WCF при запуске, поскольку они передают параметры, которые неизвестны / недоступны, пока пользователь не использует приложение (выбор элементов и т. Д.). Я попытался переместить свои вызовык WCF получателю моей наблюдаемой коллекции, но он продолжает вызывать WCF в бесконечном цикле.Во всех образцах MVVM-light, которые я видел, я не видел никого, кто бы вызывал службы WCF.Какие-нибудь предложения относительно того, куда поместить мои вызовы WCF в модели?

Ответы [ 3 ]

2 голосов
/ 31 июля 2011

Как и всегда в MVVM, нет правильного способа ... как в отношении feedom ... :-)

Вы можете поместить код в модель представления, если хотите,Однако затем вам также необходимо будет сгенерировать данные времени проектирования в модели представления - если вы хотите их использовать.

Большим недостатком этого подхода является то, что вы вводите связь между моделью представления и кодом сервиса (так как вам придется создавать экземпляр службы в модели представления).Общий подход к разделению компонентов заключается в создании интерфейса, описывающего ваш сервис, и вставке экземпляра объекта, реализующего этот интерфейс, в модель представления в его конструкторе.Это позволяет вам создавать время разработки и реализацию времени выполнения, и вашей модели представления не важно, какая из них используется - то есть объекты не связаны между собой.

Редактировать

Внедрение в моем посте не означает, , означает ли это, что вы используете контейнер / инфраструктуру для инъекций, это только означает, что вы используете интерфейс для абстрагирования своего поведения службы, а затем передаете разработчик или этот интерфейс в конструктор вашегопосмотреть модель.Теперь вы можете передавать различные реализации интерфейса при создании модели представления, например, в локаторе представления.

Предложенный шаблон называется «инверсией управления», а внедрение - это метод передачи объектов, созданных в других местах, в создаваемый вами класс.Благодаря этому ваш класс теперь защищен от каких-либо подробных знаний о разработчиках, и они становятся взаимозаменяемыми.

Инверсия контейнеров управления - таких как ninject, unity и т. Д. - просто поможет вам автоматически разрешать зависимости, однако, они не требуются для использования встроенной версии шаблона управления.

1 голос
/ 01 августа 2011

Вот мой пример моего файла CommonServiceHelper.cs

   public void GetUserSettings(UserInfoIn input, Action<UserInfoOut, Exception> callback)
    {
        var proxy = new CommonServiceClient();

        try
        {
            proxy.GetUserSettingsCompleted += (sender, eventargs) =>
            {
                var userCallback = eventargs.UserState as Action<UserInfoOut, Exception>;
                if (userCallback == null)
                    return;

                if (eventargs.Error != null)
                {
                    userCallback(null, eventargs.Error);
                    return;
                }
                userCallback(eventargs.Result, null);
            };
            proxy.GetUserSettingsAsync(input, callback);
        }
        catch (Exception ex)
        {
            proxy.Abort();
            //ErrorHelper.WriteErrorLog(ex.ToString());
        }
        finally
        {
            if (proxy.State != CommunicationState.Closed)
            {
                proxy.CloseAsync();
            }
        }
    }

Затем в ViewModel я называю его так:

               var serviceCommon = new CommonServiceHelper();
                            serviceCommon.GetUserSettings(userSettingsInput, (result, error) =>
                            {
                                if (result != null && error != null)
                                {
                                    //everything is ok
                                }
                                else
                                {
                                    //handle errors
                                }
                            });
1 голос
/ 31 июля 2011

Я не думаю, что было бы хорошо помещать вызов WCF во ViewModel, вы должны инкапсулировать вызов WCF в другом классе.Ваша ViewModel должна содержать только логику GUI.Я думаю, что вы получаете от вызова WCF модель, вы можете использовать модель для создания ViewModel.

...