start extensibility

This commit is contained in:
2020-05-19 14:42:51 +02:00
parent 36fac9257f
commit d1b3ef82eb
10 changed files with 186 additions and 32 deletions
+1 -1
View File
@@ -5,7 +5,7 @@ namespace zero.Core.Attributes
/// <summary>
/// This attribute will allow the usage of custom collection names for Raven collections
/// </summary>
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
[AttributeUsage(AttributeTargets.Interface | AttributeTargets.Class, AllowMultiple = false)]
public class CollectionAttribute : Attribute
{
public string Name { get; set; }
+22 -22
View File
@@ -32,9 +32,9 @@ namespace zero.Core.Mapper
/// <inheritdoc />
public void Add<T>() where T : IMapperConfig, new()
public void Add<T>() where T : IMapperConfig
{
T config = new T();
T config = Activator.CreateInstance<T>();
config.Configure(this);
}
@@ -54,19 +54,19 @@ namespace zero.Core.Mapper
/// <inheritdoc />
public async Task<TTarget> Map<TSource, TTarget>(TSource source) where TTarget : class, new()
public async Task<TTarget> Map<TSource, TTarget>(TSource source)
{
if (source == null)
{
return null;
return default;
}
return await Map(source, new TTarget());
return await Map(source, Activator.CreateInstance<TTarget>());
}
/// <inheritdoc />
public async Task<TTarget> Map<TSource, TTarget>(TSource source, TTarget target) where TTarget : class, new()
public async Task<TTarget> Map<TSource, TTarget>(TSource source, TTarget target)
{
if (source == null)
{
@@ -85,13 +85,13 @@ namespace zero.Core.Mapper
/// <inheritdoc />
public async Task<IEnumerable<TTarget>> Map<TSource, TTarget>(IEnumerable<TSource> source) where TTarget : class, new()
public async Task<IEnumerable<TTarget>> Map<TSource, TTarget>(IEnumerable<TSource> source)
{
IList<TTarget> target = new List<TTarget>();
foreach (TSource item in source)
{
target.Add(await Map(item, new TTarget()));
target.Add(await Map(item, Activator.CreateInstance<TTarget>()));
}
return target;
@@ -99,13 +99,13 @@ namespace zero.Core.Mapper
/// <inheritdoc />
public async Task<ListResult<TTarget>> Map<TSource, TTarget>(ListResult<TSource> source) where TTarget : class, new()
public async Task<ListResult<TTarget>> Map<TSource, TTarget>(ListResult<TSource> source)
{
IList<TTarget> target = new List<TTarget>();
foreach (TSource item in source.Items)
{
target.Add(await Map(item, new TTarget()));
target.Add(await Map(item, Activator.CreateInstance<TTarget>()));
}
return new ListResult<TTarget>(target, source.TotalItems, source.Page, source.PageSize)
@@ -116,19 +116,19 @@ namespace zero.Core.Mapper
/// <inheritdoc />
public async Task<EntityResult<TTarget>> Map<TSource, TTarget>(EntityResult<TSource> source) where TTarget : class, new()
public async Task<EntityResult<TTarget>> Map<TSource, TTarget>(EntityResult<TSource> source)
{
return new EntityResult<TTarget>()
{
IsSuccess = source.IsSuccess,
Errors = source.Errors,
Model = await Map(source.Model, new TTarget())
Model = await Map(source.Model, Activator.CreateInstance<TTarget>())
};
}
/// <inheritdoc />
public void CreateMap<TSource, TTarget>(Action<TSource, TTarget> map) where TTarget : class, new()
public void CreateMap<TSource, TTarget>(Action<TSource, TTarget> map)
{
Maps.Add<TSource, TTarget>((source, target) =>
{
@@ -139,7 +139,7 @@ namespace zero.Core.Mapper
/// <inheritdoc />
public void CreateMap<TSource, TTarget>(Func<TSource, TTarget, IAsyncDocumentSession, Task> map) where TTarget : class, new()
public void CreateMap<TSource, TTarget>(Func<TSource, TTarget, IAsyncDocumentSession, Task> map)
{
Maps.Add<TSource, TTarget>(async (source, target) =>
{
@@ -220,7 +220,7 @@ namespace zero.Core.Mapper
public interface IMapper
{
/// <inheritdoc />
void Add<T>() where T : IMapperConfig, new();
void Add<T>() where T : IMapperConfig;
/// <inheritdoc />
void Add(Assembly assembly);
@@ -228,34 +228,34 @@ namespace zero.Core.Mapper
/// <summary>
/// Map an object to the target type
/// </summary>
Task<TTarget> Map<TSource, TTarget>(TSource source) where TTarget : class, new();
Task<TTarget> Map<TSource, TTarget>(TSource source);
/// <summary>
/// Map an object to the target type given an already existing target instance
/// </summary>
Task<TTarget> Map<TSource, TTarget>(TSource source, TTarget target) where TTarget : class, new();
Task<TTarget> Map<TSource, TTarget>(TSource source, TTarget target);
/// <summary>
/// Map a list of objects to the target type
/// </summary>
Task<IEnumerable<TTarget>> Map<TSource, TTarget>(IEnumerable<TSource> source) where TTarget : class, new();
Task<IEnumerable<TTarget>> Map<TSource, TTarget>(IEnumerable<TSource> source);
/// <summary>
/// Map a list result containing objects to the target type
/// </summary>
Task<ListResult<TTarget>> Map<TSource, TTarget>(ListResult<TSource> source) where TTarget : class, new();
Task<ListResult<TTarget>> Map<TSource, TTarget>(ListResult<TSource> source);
/// <summary>
/// Map an entity result to the target type
/// </summary>
Task<EntityResult<TTarget>> Map<TSource, TTarget>(EntityResult<TSource> source) where TTarget : class, new();
Task<EntityResult<TTarget>> Map<TSource, TTarget>(EntityResult<TSource> source);
/// <summary>
/// Create a mapping from source to target object
/// </summary>
void CreateMap<TSource, TTarget>(Action<TSource, TTarget> map) where TTarget : class, new();
void CreateMap<TSource, TTarget>(Action<TSource, TTarget> map);
/// <inheritdoc />
void CreateMap<TSource, TTarget>(Func<TSource, TTarget, IAsyncDocumentSession, Task> map) where TTarget : class, new();
void CreateMap<TSource, TTarget>(Func<TSource, TTarget, IAsyncDocumentSession, Task> map);
}
}
+15
View File
@@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
namespace zero.Core.Options
{
public class TypeOptions : IZeroCollectionOptions
{
Dictionary<Type, Type> Items { get; set; } = new Dictionary<Type, Type>();
internal void Add<T, TTarget>() where TTarget : T
{
Items[typeof(T)] = typeof(TTarget);
}
}
}
+62 -1
View File
@@ -1,5 +1,8 @@
using System.Collections.Generic;
using FluentValidation;
using System.Collections.Generic;
using zero.Core.Mapper;
using zero.Core.Plugins;
using zero.Core.Renderer;
namespace zero.Core.Options
{
@@ -19,6 +22,7 @@ namespace zero.Core.Options
Settings = new SettingsOptions();
Spaces = new SpaceOptions();
Mapper = new MapperOptions();
Types = new TypeOptions();
}
/// <inheritdoc />
@@ -65,6 +69,20 @@ namespace zero.Core.Options
/// <inheritdoc />
public MapperOptions Mapper { get; private set; }
/// <inheritdoc />
public TypeOptions Types { get; private set; }
/// <inheritdoc />
public void Extend<T, TTarget>() where TTarget : T
{
Types.Add<T, TTarget>();
}
public ZeroExtend<T> Extend<T>()
{
return new ZeroExtend<T>();
}
}
@@ -149,10 +167,53 @@ namespace zero.Core.Options
/// </summary>
MapperOptions Mapper { get; }
/// <summary>
///
/// </summary>
TypeOptions Types { get; }
/// <inheritdoc />
void Extend<T, TTarget>() where TTarget : T;
ZeroExtend<T> Extend<T>();
/// <summary>
/// Default settings for the backoffice
/// </summary>
//IZeroPluginConfiguration Backoffice { get; set; }
}
public class ZeroExtend<T>
{
public ZeroExtend<T> Use<TTarget>() where TTarget : T
{
return this;
}
public ZeroExtend<T> Use<TTarget, TRenderer>()
where TTarget : T
where TRenderer : IRenderer<T>
{
return this;
}
public ZeroExtend<T> Use<TTarget, TRenderer, TValidator>()
where TTarget : T
where TRenderer : IRenderer<T>
where TValidator : IValidator<T>
{
return this;
}
public ZeroExtend<T> Use<TTarget, TRenderer, TValidator, TMapper>()
where TTarget : T
where TRenderer : IRenderer<T>
where TValidator : IValidator<T>
where TMapper : IMapperConfig
{
return this;
}
}
}
+1 -1
View File
@@ -22,7 +22,7 @@ namespace zero.Core.Renderer
}
public abstract class AbstractRenderer<T> : IRenderer<T>, IRenderer where T : new()
public abstract class AbstractRenderer<T> : IRenderer<T>, IRenderer
{
const string METHOD_FIELD = "field";
+9
View File
@@ -0,0 +1,9 @@
using zero.Commerce.Entities;
namespace zero.Debug.Models
{
public class SalesChannel : Channel
{
public string Description { get; set; }
}
}
+46
View File
@@ -0,0 +1,46 @@
using zero.Commerce.Entities;
using zero.Core.Renderer;
using zero.Debug.Models;
namespace zero.Commerce.Backoffice
{
public class SalesChannelRenderer : AbstractRenderer<SalesChannel>
{
public SalesChannelRenderer() : base()
{
Field(x => x.Name, required: false).Text();
//Field(x => x.Name, "@ui.name", required: true, noDescription: true).Text();
//Field(x => x.CheckoutType).State(opts =>
//{
// opts.Add("@channel.checkout_states.none", ChannelCheckoutType.None);
// opts.Add("@channel.checkout_states.order", ChannelCheckoutType.Order);
// opts.Add("@channel.checkout_states.request", ChannelCheckoutType.Request);
// opts.Add("@channel.checkout_states.both", ChannelCheckoutType.All);
//});
//Field(x => x.ProductSorting).State(opts =>
//{
// opts.Add("@channel.sorting_states.relevance", ChannelProductSorting.Relevance);
// opts.Add("@channel.sorting_states.new", ChannelProductSorting.New);
// opts.Add("@channel.sorting_states.price", ChannelProductSorting.Price);
//});
//Tab("@channel.tabs.theme", () =>
//{
// Field(x => x.Theme.ImageId, required: true).Text();
//});
//Tab("@channel.tabs.settings", () =>
//{
// Field(x => x.ClientNo).Text();
// Field(x => x.SortLetter).Text(opts =>
// {
// opts.Classes.Add("is-short");
// opts.MaxLength = 1;
// });
//});
}
}
}
+14
View File
@@ -1,3 +1,4 @@
using FluentValidation;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
@@ -5,6 +6,10 @@ using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using zero.Commerce.Backoffice;
using zero.Commerce.Entities;
using zero.Core.Renderer;
using zero.Debug.Models;
using zero.TestData;
using zero.Web;
@@ -39,6 +44,15 @@ namespace zero.Debug
zero.AddPlugin<TestPlugin>();
zero.AddPlugin<Commerce.CommercePlugin>();
zero.WithOptions(opts =>
{
opts.Extend<IChannel, SalesChannel>();
//IRenderer<IChannel> renderer = (IRenderer<IChannel>)new SalesChannelRenderer();
//renderer.
//opts.Renderers.Extend<IChannel, SalesChannelRenderer>();
});
services.AddMvc();
services.Configure<IISOptions>(opts => opts.AutomaticAuthentication = false);
+3
View File
@@ -6,6 +6,9 @@
</div>
<aside v-if="index === 0" class="ui-view-box-aside">
<ui-property label="@ui.active" :vertical="true" :is-text="true">
<ui-toggle v-model="value.isActive" />
</ui-property>
<ui-property label="@ui.id" :vertical="true" :is-text="true">
{{value.id}}
</ui-property>
+13 -7
View File
@@ -1,15 +1,13 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Threading.Tasks;
using zero.Core;
using zero.Core.Api;
using zero.Core.Entities;
using zero.Core.Identity;
using zero.Core.Mapper;
using zero.Core.Options;
using zero.Web.Filters;
using zero.Web.Mapper;
using zero.Web.Models;
namespace zero.Web.Controllers
@@ -44,6 +42,14 @@ namespace zero.Web.Controllers
}
protected JsonResult AsJson(object data)
{
JsonSerializerSettings settings = JsonConvert.DefaultSettings();
settings.TypeNameHandling = TypeNameHandling.Objects;
return Json(data, settings);
}
protected async Task<IActionResult> As<T, TTarget>(T model) where TTarget : class, new() where T : IZeroEntity
{
if (model == null)
@@ -64,7 +70,7 @@ namespace zero.Web.Controllers
//model.CanEdit =
}
return Json(result);
return AsJson(result);
}
@@ -75,7 +81,7 @@ namespace zero.Web.Controllers
return new StatusCodeResult(404);
}
return Json(await Mapper.Map<T, TTarget>(model));
return AsJson(await Mapper.Map<T, TTarget>(model));
}
@@ -86,7 +92,7 @@ namespace zero.Web.Controllers
return new StatusCodeResult(404);
}
return Json(await Mapper.Map<T, TTarget>(model));
return AsJson(await Mapper.Map<T, TTarget>(model));
}
protected async Task<IActionResult> As<T, TTarget>(EntityResult<T> model) where TTarget : class, new() where T : IZeroEntity
@@ -96,7 +102,7 @@ namespace zero.Web.Controllers
return new StatusCodeResult(404);
}
return Json(await Mapper.Map<T, TTarget>(model));
return AsJson(await Mapper.Map<T, TTarget>(model));
}
protected async Task<TTarget> Map<T, TTarget>(T model) where TTarget : class, new()