Add Content lookup markupextension

This commit is contained in:
Daniel Clark
2022-12-14 20:07:45 +00:00
parent b77ee21d56
commit f7e682e0db
32 changed files with 783 additions and 229 deletions
+24
View File
@@ -0,0 +1,24 @@
using Mediator;
namespace Toolkit.Framework.Foundation;
public record Content : IRequest<object?>
{
public Content(string name, params object?[] parameters)
{
Name = name;
Parameters = parameters;
}
public Content(Type type, params object?[] parameters)
{
Type = type;
Parameters = parameters;
}
public Type? Type { get; }
public string? Name { get; }
public object?[] Parameters { get; }
}
@@ -0,0 +1,23 @@
using Microsoft.Extensions.DependencyInjection;
using System.Collections.ObjectModel;
namespace Toolkit.Framework.Foundation;
public class ContentTemplateBuilder : IContentTemplateBuilder
{
private readonly List<IContentTemplateDescriptor> descriptors = new();
public IReadOnlyCollection<IContentTemplateDescriptor> Descriptors => new ReadOnlyCollection<IContentTemplateDescriptor>(descriptors);
public IContentTemplateBuilder Add<TViewModel, TView>(string name, ServiceLifetime lifetime = ServiceLifetime.Transient)
{
descriptors.Add(new ContentTemplateDescriptor(typeof(TViewModel), typeof(TView), name, lifetime));
return this;
}
public IContentTemplateBuilder Add<TViewModel, TView>(ServiceLifetime lifetime = ServiceLifetime.Transient)
{
descriptors.Add(new ContentTemplateDescriptor(typeof(TViewModel), typeof(TView), null, lifetime));
return this;
}
}
@@ -0,0 +1,25 @@
using Microsoft.Extensions.DependencyInjection;
namespace Toolkit.Framework.Foundation;
public class ContentTemplateDescriptor : IContentTemplateDescriptor
{
public ContentTemplateDescriptor(Type dataType,
Type templateType,
string? name = null,
ServiceLifetime lifetime = ServiceLifetime.Transient)
{
TemplateType = templateType;
ContentType = dataType;
Name = name;
Lifetime = lifetime;
}
public ServiceLifetime Lifetime { get; }
public Type TemplateType { get; }
public Type ContentType { get; }
public string? Name { get; }
}
@@ -0,0 +1,41 @@
namespace Toolkit.Framework.Foundation;
public class ContentTemplateDescriptorProvider : IContentTemplateDescriptorProvider
{
private readonly IReadOnlyCollection<IContentTemplateDescriptor> descriptors;
public ContentTemplateDescriptorProvider(IReadOnlyCollection<IContentTemplateDescriptor> descriptors)
{
this.descriptors = descriptors;
}
public IContentTemplateDescriptor? Get(string name)
{
if (descriptors.FirstOrDefault(x => x.Name == name) is IContentTemplateDescriptor descriptor)
{
return descriptor;
}
return null;
}
public IContentTemplateDescriptor? Get(Type type)
{
if (descriptors.FirstOrDefault(x => x.ContentType == type) is IContentTemplateDescriptor descriptor)
{
return descriptor;
}
return null;
}
public IContentTemplateDescriptor? Get<T>()
{
if (descriptors.FirstOrDefault(x => x.ContentType == typeof(T)) is IContentTemplateDescriptor descriptor)
{
return descriptor;
}
return null;
}
}
@@ -0,0 +1,42 @@
using System.Diagnostics.CodeAnalysis;
namespace Toolkit.Framework.Foundation;
public class ContentTemplateFactory : IContentTemplateFactory
{
private readonly Dictionary<object, object> cache = new();
private readonly IContentTemplateDescriptorProvider provider;
private readonly IServiceFactory serviceFactory;
public ContentTemplateFactory(IContentTemplateDescriptorProvider provider,
IServiceFactory serviceFactory)
{
this.provider = provider;
this.serviceFactory = serviceFactory;
}
public virtual object? Create([MaybeNull] object? data)
{
if (data is null)
{
return null;
}
if (cache.TryGetValue(data, out object? template))
{
return template;
}
if (provider.Get(data.GetType()) is IContentTemplateDescriptor descriptor)
{
template = serviceFactory.Create(descriptor.TemplateType);
if (template is ICache cache)
{
this.cache[data] = cache;
}
}
return template;
}
}
@@ -0,0 +1,12 @@
using Microsoft.Extensions.DependencyInjection;
namespace Toolkit.Framework.Foundation;
public interface IContentTemplateBuilder
{
IReadOnlyCollection<IContentTemplateDescriptor> Descriptors { get; }
IContentTemplateBuilder Add<TViewModel, TView>(string name, ServiceLifetime lifetime = ServiceLifetime.Transient);
IContentTemplateBuilder Add<TViewModel, TView>(ServiceLifetime lifetime = ServiceLifetime.Transient);
}
@@ -0,0 +1,14 @@
using Microsoft.Extensions.DependencyInjection;
namespace Toolkit.Framework.Foundation;
public interface IContentTemplateDescriptor
{
Type ContentType { get; }
ServiceLifetime Lifetime { get; }
string? Name { get; }
Type TemplateType { get; }
}
@@ -0,0 +1,10 @@
namespace Toolkit.Framework.Foundation;
public interface IContentTemplateDescriptorProvider
{
IContentTemplateDescriptor? Get(string name);
IContentTemplateDescriptor? Get(Type type);
IContentTemplateDescriptor? Get<T>();
}
@@ -0,0 +1,8 @@
using System.Diagnostics.CodeAnalysis;
namespace Toolkit.Framework.Foundation;
public interface IContentTemplateFactory
{
object? Create([MaybeNull] object? content);
}
@@ -0,0 +1,5 @@
namespace Toolkit.Framework.Foundation;
public interface IContentTemplateSelector
{
}
@@ -0,0 +1,6 @@
namespace Toolkit.Framework.Foundation;
public interface INamedContentTemplateFactory
{
object? Create(string name);
}
@@ -0,0 +1,6 @@
namespace Toolkit.Framework.Foundation;
public interface INamedContentFactory
{
object? Create(string name, params object?[] parameters);
}
@@ -0,0 +1,6 @@
namespace Toolkit.Framework.Foundation;
public interface ITypedContentFactory
{
object? Create(Type type, params object?[] parameters);
}
@@ -0,0 +1,35 @@
namespace Toolkit.Framework.Foundation;
public class NamedContentFactory : INamedContentFactory
{
private readonly Dictionary<string, object> cache = new();
private readonly IReadOnlyCollection<IContentTemplateDescriptor> descriptors;
private readonly IServiceFactory serviceFactory;
public NamedContentFactory(IReadOnlyCollection<IContentTemplateDescriptor> descriptors,
IServiceFactory serviceFactory)
{
this.descriptors = descriptors;
this.serviceFactory = serviceFactory;
}
public virtual object? Create(string name, params object[] parameters)
{
if (cache.TryGetValue(name, out object? data))
{
return data;
}
if (descriptors.FirstOrDefault(x => x.Name == name) is IContentTemplateDescriptor descriptor)
{
data = parameters is { Length: > 0 } ? serviceFactory.Create<object>(descriptor.ContentType, parameters) : serviceFactory.Create(descriptor.ContentType);
if (data is ICache cache)
{
this.cache[name] = cache;
}
}
return data;
}
}
@@ -0,0 +1,40 @@
namespace Toolkit.Framework.Foundation;
public class NamedContentTemplateFactory : INamedContentTemplateFactory
{
private readonly Dictionary<string, object> cache = new();
private readonly IContentTemplateDescriptorProvider provider;
private readonly IServiceFactory serviceFactory;
public NamedContentTemplateFactory(IContentTemplateDescriptorProvider provider,
IServiceFactory serviceFactory)
{
this.provider = provider;
this.serviceFactory = serviceFactory;
}
public virtual object? Create(string name)
{
if (cache.TryGetValue(name, out object? view))
{
return view;
}
if (provider.Get(name) is IContentTemplateDescriptor descriptor)
{
view = serviceFactory.Create(descriptor.TemplateType);
if (view is ICache cache)
{
this.cache[name] = cache;
}
if (descriptor.GetType().GenericTypeArguments is { Length: 2 })
{
(descriptor as dynamic).ViewInvoker?.Invoke(view);
}
}
return view;
}
}
@@ -0,0 +1,35 @@
namespace Toolkit.Framework.Foundation;
public class TypedContentFactory : ITypedContentFactory
{
private readonly Dictionary<Type, object> cache = new();
private readonly IReadOnlyCollection<IContentTemplateDescriptor> descriptors;
private readonly IServiceFactory serviceFactory;
public TypedContentFactory(IReadOnlyCollection<IContentTemplateDescriptor> descriptors,
IServiceFactory serviceFactory)
{
this.descriptors = descriptors;
this.serviceFactory = serviceFactory;
}
public virtual object? Create(Type type, params object[] parameters)
{
if (cache.TryGetValue(type, out object? data))
{
return data;
}
if (descriptors.FirstOrDefault(x => x.ContentType == type) is IContentTemplateDescriptor descriptor)
{
data = parameters is { Length: > 0 } ? serviceFactory.Create<object>(descriptor.ContentType, parameters) : serviceFactory.Create(descriptor.ContentType);
if (data is ICache cache)
{
this.cache[type] = cache;
}
}
return data;
}
}