forked from amkovkov/GranuSightSoftware2
77 lines
3.2 KiB
C#
77 lines
3.2 KiB
C#
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;
|
|
}
|
|
}
|