Использовать метод Service в View-Model [WPF-MVVM] - PullRequest
0 голосов
/ 14 декабря 2010

Привет, попробуй перенести мое приложение Winform в WPF с MVVM.Я использую Caliburn Micro и MEF в качестве IoC.У меня есть служба во внешней DLL -> Pokec_Toolki.dll , и эти службы используют другие внешние DLL, такие как JSON.NET, HtmlAgilityPack..etc (сторонние библиотеки).

Мой сервис выглядитthis:

public interface IPokecConnection
{
    PokecAccount LogOn(string nick, string password);
    bool LogOff(PokecAccount account);
}

[Export(typeof(IPokecConnection))]
public class PokecConnection : IPokecConnection
{
}

Для моего Сервиса я создаю потребитель для класса PokecConnection, он находится в той же сборке, что и Сервис:

[Export]
public class PokecConnectionConsumer
{
    private readonly IPokecConnection _pokecConn;

    [ImportingConstructor]
    public PokecConnectionConsumer(IPokecConnection pokecConn)
    {
        _pokecConn = pokecConn;
    }

    public PokecAccount MethodWrapperForLogOn(string name, string  password)
    {
        return _pokecConn.LogOn(name, password);
    }

}

У меня простой вид с 2 текстовыми полями и 1 кнопкой.Я связываю событие нажатием кнопки с условным обозначением калибровки на модели представления.

Представление:

<Button Micro:Message.Attach="[Event Click]=[Action LogOn(tbNick.Text,tbPassword.Text)]"
        Content="Prihlás ma"
        Width="100" 
        Grid.Row="2"
        Height="25" Margin="4,4,4,4" />

Мне нужен метод обслуживания в моей модели представления.Итак, в view-модели у меня есть это:

[Export(typeof(IShellViewModel))]
public class ShellViewModel : Screen, IShellViewModel, IDataErrorInfo
{

    private PokecConnectionConsumer _connConsumer;

    protected override void OnInitialize()
    {
        base.OnInitialize();

        var mycatalog = new AssemblyCatalog(System.Reflection.Assembly.LoadFrom("Pokec_Toolkit.dll"));

        var container = new CompositionContainer(mycatalog);
        container.ComposeParts(this);

        _connConsumer = container.GetExportedValue<PokecConnectionConsumer>();
    }

    //this method is bind on event click of button in view
    public void LogOn(string nick, string password)
    {
        //call method LogOn from class PokecConnection in external dll through PokecConnectionConsumer

        var accout = _connConsumer.MethodWrapperForLogOn(nick, password);

        // in this place if account is not null, I need close this view and create new view MainView 
        //a send to the MainViewModel constructor as argument variable account

        //some test 
        MessageBox.Show(accout.SessionId);
    }


}

У меня есть такой вопрос:

  1. Во-первых, хорошо ли создавать потребителя для класса обслуживания во внешней dll?В моем случае PokecConnectionConsumer ** и этот класс находится в той же сборке, что и класс обслуживания PokecConnection?
  2. Это правильный способ загрузить внешнюю сборку в view-модель в методе OnInitialize?
  3. Это правильный вызовСервисный метод в view-модели?
  4. Существует ли более подходящий способ, как связать метод с внешней dll на управление видом?Мне нужно просто загрузить внешнюю DLL в приложение wpf с MVVM и метод привязки службы для элементов управления в представлениях.Каков наилучший способ?

Как закрыть действительный вид и создать новый вид, а также активировать этот вид.Мне нужно отправить в качестве аргумента переменную из view-модели в другой конструктор vie-модели. **

МОЕ РЕШЕНИЕ:

Я создаю интерфейсную сборку и отсылаю этосборка во внешней сервисной dll, а также в приложении wpf.

В загрузчике я загружаю эту сборку с отражением:

    var catalog =
    new AggregateCatalog(
        AssemblySource.Instance.Select(x => new AssemblyCatalog(x)).OfType<ComposablePartCatalog>());

catalog.Catalogs.Add(
    new AssemblyCatalog(string.Format(
        CultureInfo.InvariantCulture, "{0}{1}", System.IO.Directory.GetCurrentDirectory(), @"\Pokec_Toolkit.dll")));

_container = new CompositionContainer(catalog);

Чем я создаю класс проводника:

public interface IShellViewModel
{
    void ShowLogOnView();
    void ShowMessengerView();
}

[Export(typeof(IShellViewModel))]
public class ShellViewModel : Conductor<IScreen>, IShellViewModel
{
    public ShellViewModel()
    {
        ShowLogOnView();
    }

    public void ShowLogOnView()
    {
        ActivateItem(IoC.Get<LogOnViewModel>());
    }

    public void ShowMessengerView()
    {
        ActivateItem(IoC.Get<MessengerViewModel>());
    }
}

И в View-модели у меня есть это:

  [Export]
    public class LogOnViewModel : Screen, IDataErrorInfo, ILogOnViewModel
    {

        [Import]
        private IShellViewModel _shellViewModel;

        [Import]
        private IPokecConnection _pokecConn;

//this method is bind on event click of button
        public void LogOn(string nick, string password)
        {
            //SHOW NEW WIEW
           _shellViewModel.ShowMessengerView();
        }
    }

1 Ответ

0 голосов
/ 14 декабря 2010

1) Да, так что если внешняя зависимость изменяется, вам не нужно перекомпилировать свой пользовательский интерфейс. Также он должен быть вне логики View / VM.

2) Не боюсь. Создайте для него отдельный класс обслуживания.

3) То же самое, создайте для него отдельный класс обслуживания и используйте его в ВМ.

4) Ну, вы все равно должны загрузить DLL. Так что загружайте его в сервисный класс.

...