Реализовать загрузчик Caliburn - откуда звонить - PullRequest
0 голосов
/ 16 января 2020

Я пытаюсь реализовать Caliburn.Micro и bootstrap в моем Xamarin Forms приложении. Я не уверен, куда я должен позвонить своему классу Bootstraper, чтобы правильно запустить приложение. У меня также есть проблемы с переопределением метода OnStartup внутри моего класса Bootstrapper, потому что он говорит, что не может найти: StartupEventArgs, а внутри важен вызов: DisplayRootViewFor<ShellView>();, поэтому я прокомментировал эту часть кода.

Приложение:

public partial class App : Application
{
        public App()
        {
            InitializeComponent();
        }

        protected override void OnStart()
        {
        }

        protected override void OnSleep()
        {
        }

        protected override void OnResume()
        {
        }
}

Приложение.xaml (куда я положил ключ Bootstrapper)

<?xml version="1.0" encoding="utf-8" ?>
<Application xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:d="http://xamarin.com/schemas/2014/forms/design"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:xamarinFormsDiEaWin="clr-namespace:XamarinFormsDiEaWin;assembly=XamarinFormsDiEaWin"
             mc:Ignorable="d"
             x:Class="XamarinFormsDiEaWin.App">
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary>
                    <xamarinFormsDiEaWin:Bootstrapper x:Key="Bootstrapper" />
                </ResourceDictionary>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>

Bootstrapper

public class Bootstrapper : BootstrapperBase
{
    private SimpleContainer _container = new SimpleContainer();

    public Bootstrapper() => Initialize();

    protected override void Configure()
    {
        _container.Instance(_container);
        _container
            .Singleton<IWindowManager, WindowManager>()
            .Singleton<IEventAggregator, EventAggregator>();

        GetType().Assembly.GetTypes()
            .Where(type => type.IsClass)
            .Where(type => type.Name.EndsWith("ViewModel"))
            .ToList()
            .ForEach(viewModelType => _container.RegisterPerRequest(
                viewModelType, viewModelType.ToString(), viewModelType));
    }

    protected override object GetInstance(Type service, string key)
    {
        return _container.GetInstance(service, key);
    }

    protected override IEnumerable<object> GetAllInstances(Type service)
    {
        return _container.GetAllInstances(service);
    }

    protected override void BuildUp(object instance)
    {
        _container.BuildUp(instance);
    }

    //protected override void OnStartup(object sender, System.Windows.StartupEventArgs e)
    //{
    //    DisplayRootViewFor<ShellView>();
    //}
}

ShellViewModel:

public class ShellViewModel : Conductor<object>, IHandle<LogOnEventModel>
{
    private IEventAggregator _events;
    private SalesViewModel _salesVM;
    private SimpleContainer _container;

    public ShellViewModel(IEventAggregator events, SalesViewModel salesVm,
        SimpleContainer container)
    {
        _events = events;
        _salesVM = salesVm;
        _container = container;

        _events.Subscribe(this);
        ActivateItem(_container.GetInstance<LoginViewModel>());
    }

    public void Handle(LogOnEventModel message)
    {
        ActivateItem(_salesVM);
    }
}

1 Ответ

0 голосов
/ 23 января 2020

Должен сказать, что я использую версию 4. *. Все будет ссылаться на эту версию.

Ваш Bootstrapper отражает мое собственное, поэтому он должен работать правильно.

Вот несколько отличий:

protected override void OnStartup(object sender, StartupEventArgs e)
    {            
        DisplayRootViewFor<IShell>()
            .GetAwaiter()
            .GetResult();
    }

^ это чтобы избежать асинхронности c void.

private SimpleContainer Container;

^ Я запускаю контейнер из переопределения конфигурации. Пример:

protected override void Configure()
{
    Container = new SimpleContainer();

    //FrameWork
    Container.Singleton<IWindowManager, WindowManager>();
    Container.Singleton<IEventAggregator, EventAggregator>();

    ...Rest of Your Models & Services.
}

Переопределение для StartupEvent происходит из пространства имен System. Windows Вы правильно отметили, я бы проверил браузер объектов, чтобы убедиться, что он существует в вашем проекте.

Внутри файла App.xaml.cs Должно быть только следующее:

public partial class App : Application
{
    public App()
    {
        InitializeComponent();
    }
}

_container.Instance(_container);

^ Не уверен, почему вы это делаете, вы называете себя.

ваш App.xaml - это то место, откуда вы вызываете загрузчик.

private IEventAggregator _events;    
private SimpleContainer _container;

^ Они должны быть доступны только для чтения.

 ActivateItem(_container.GetInstance<LoginViewModel>());

Это должно быть введено, если вы не можете по какой-то причине, тогда используйте Io C. Вы не должны вызывать контейнер напрямую.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...