forked from amkovkov/GranuSightSoftware2
feat: MainView
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.Templates;
|
||||
|
||||
using GSS2.UI.Core.ViewModels;
|
||||
|
||||
namespace GSS2;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="DependencyInjectionViewLocator"/> - интерфейс между Avalonia и механизмом DI (Dependency Injection)
|
||||
/// из Microsoft.Extensions.Hosting.<br/>
|
||||
/// Создаёт View для переданной ViewModel.<br/>
|
||||
/// Обязательным условием его работы является, то что:
|
||||
/// <list type="bullet">
|
||||
/// <item>Класс <i>View</i> находится в пространстве имён <i>SomeNameSpace.Views</i> и имеет имя <i>SomeClassView</i></item>
|
||||
/// <item>Класс <i>ViewModel</i> находится в пространстве имён <i>SomeNameSpace.ViewModels</i> и имеет имя <i>SomeClassViewModel</i></item>
|
||||
/// <item>Класс <i>ViewModel</i> наследован от <see cref="ViewModelBase"/></item>
|
||||
/// <item>Класс <i>View</i> наследован от <see cref="Control"/></item>
|
||||
/// </list>
|
||||
/// </summary>
|
||||
public class DependencyInjectionViewLocator : IDataTemplate
|
||||
{
|
||||
private readonly ILogger<DependencyInjectionViewLocator> _logger;
|
||||
private readonly IServiceProvider _services;
|
||||
|
||||
public DependencyInjectionViewLocator(ILogger<DependencyInjectionViewLocator> logger, IServiceProvider services)
|
||||
{
|
||||
_logger = logger;
|
||||
_services = services;
|
||||
}
|
||||
|
||||
public bool Match(object? data) => data is ViewModelBase;
|
||||
|
||||
public Control? Build(object? data)
|
||||
{
|
||||
// Если data - null или каким-то образом не ViewModelBase, то возвращаем null
|
||||
if (data is not ViewModelBase viewModel)
|
||||
return null;
|
||||
|
||||
// Получаем имя класса ViewModel с полным описанием сборки
|
||||
var viewModelName = viewModel.GetType().AssemblyQualifiedName;
|
||||
if (viewModelName is null)
|
||||
{
|
||||
_logger.LogError("Не удалось получить имя класса ViewModel: {}", viewModel);
|
||||
return new Control();
|
||||
}
|
||||
|
||||
// Заменяем ".ViewModel" на ".View" в имени класса ViewModel и получаем имя класса View и его тип
|
||||
var viewName = viewModelName.Replace("ViewModel", "View");
|
||||
var viewType = Type.GetType(viewName);
|
||||
if (viewType is null)
|
||||
{
|
||||
_logger.LogError("Не удалось найти класс View \"{}\"", viewName);
|
||||
return new Control();
|
||||
}
|
||||
|
||||
// Ищем тип View в сервисах
|
||||
var view = _services.GetService(viewType);
|
||||
if (view is null)
|
||||
{
|
||||
_logger.LogError("Класс View \"{}\" не зарегистрирован", viewName);
|
||||
return new Control();
|
||||
}
|
||||
if (view is not Control control)
|
||||
{
|
||||
_logger.LogError("Класс View \"{}\" не наследован от Control", viewName);
|
||||
return new Control();
|
||||
}
|
||||
|
||||
control.DataContext = viewModel;
|
||||
return control;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user