diff --git a/zero.Core/Attributes/CollectionAttribute.cs b/zero.Core/Attributes/CollectionAttribute.cs
index 306fcc21..b6c4d9a6 100644
--- a/zero.Core/Attributes/CollectionAttribute.cs
+++ b/zero.Core/Attributes/CollectionAttribute.cs
@@ -5,7 +5,7 @@ namespace zero.Core.Attributes
///
/// This attribute will allow the usage of custom collection names for Raven collections
///
- [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
+ [AttributeUsage(AttributeTargets.Interface | AttributeTargets.Class, AllowMultiple = false)]
public class CollectionAttribute : Attribute
{
public string Name { get; set; }
diff --git a/zero.Core/Mapper/DefaultMapper.cs b/zero.Core/Mapper/DefaultMapper.cs
index 59691fcf..3a5cb9af 100644
--- a/zero.Core/Mapper/DefaultMapper.cs
+++ b/zero.Core/Mapper/DefaultMapper.cs
@@ -32,9 +32,9 @@ namespace zero.Core.Mapper
///
- public void Add() where T : IMapperConfig, new()
+ public void Add() where T : IMapperConfig
{
- T config = new T();
+ T config = Activator.CreateInstance();
config.Configure(this);
}
@@ -54,19 +54,19 @@ namespace zero.Core.Mapper
///
- public async Task Map(TSource source) where TTarget : class, new()
+ public async Task Map(TSource source)
{
if (source == null)
{
- return null;
+ return default;
}
- return await Map(source, new TTarget());
+ return await Map(source, Activator.CreateInstance());
}
///
- public async Task Map(TSource source, TTarget target) where TTarget : class, new()
+ public async Task Map(TSource source, TTarget target)
{
if (source == null)
{
@@ -85,13 +85,13 @@ namespace zero.Core.Mapper
///
- public async Task> Map(IEnumerable source) where TTarget : class, new()
+ public async Task> Map(IEnumerable source)
{
IList target = new List();
foreach (TSource item in source)
{
- target.Add(await Map(item, new TTarget()));
+ target.Add(await Map(item, Activator.CreateInstance()));
}
return target;
@@ -99,13 +99,13 @@ namespace zero.Core.Mapper
///
- public async Task> Map(ListResult source) where TTarget : class, new()
+ public async Task> Map(ListResult source)
{
IList target = new List();
foreach (TSource item in source.Items)
{
- target.Add(await Map(item, new TTarget()));
+ target.Add(await Map(item, Activator.CreateInstance()));
}
return new ListResult(target, source.TotalItems, source.Page, source.PageSize)
@@ -116,19 +116,19 @@ namespace zero.Core.Mapper
///
- public async Task> Map(EntityResult source) where TTarget : class, new()
+ public async Task> Map(EntityResult source)
{
return new EntityResult()
{
IsSuccess = source.IsSuccess,
Errors = source.Errors,
- Model = await Map(source.Model, new TTarget())
+ Model = await Map(source.Model, Activator.CreateInstance())
};
}
///
- public void CreateMap(Action map) where TTarget : class, new()
+ public void CreateMap(Action map)
{
Maps.Add((source, target) =>
{
@@ -139,7 +139,7 @@ namespace zero.Core.Mapper
///
- public void CreateMap(Func map) where TTarget : class, new()
+ public void CreateMap(Func map)
{
Maps.Add(async (source, target) =>
{
@@ -220,7 +220,7 @@ namespace zero.Core.Mapper
public interface IMapper
{
///
- void Add() where T : IMapperConfig, new();
+ void Add() where T : IMapperConfig;
///
void Add(Assembly assembly);
@@ -228,34 +228,34 @@ namespace zero.Core.Mapper
///
/// Map an object to the target type
///
- Task Map(TSource source) where TTarget : class, new();
+ Task Map(TSource source);
///
/// Map an object to the target type given an already existing target instance
///
- Task Map(TSource source, TTarget target) where TTarget : class, new();
+ Task Map(TSource source, TTarget target);
///
/// Map a list of objects to the target type
///
- Task> Map(IEnumerable source) where TTarget : class, new();
+ Task> Map(IEnumerable source);
///
/// Map a list result containing objects to the target type
///
- Task> Map(ListResult source) where TTarget : class, new();
+ Task> Map(ListResult source);
///
/// Map an entity result to the target type
///
- Task> Map(EntityResult source) where TTarget : class, new();
+ Task> Map(EntityResult source);
///
/// Create a mapping from source to target object
///
- void CreateMap(Action map) where TTarget : class, new();
+ void CreateMap(Action map);
///
- void CreateMap(Func map) where TTarget : class, new();
+ void CreateMap(Func map);
}
}
\ No newline at end of file
diff --git a/zero.Core/Options/TypeOptions.cs b/zero.Core/Options/TypeOptions.cs
new file mode 100644
index 00000000..256c122c
--- /dev/null
+++ b/zero.Core/Options/TypeOptions.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+
+namespace zero.Core.Options
+{
+ public class TypeOptions : IZeroCollectionOptions
+ {
+ Dictionary Items { get; set; } = new Dictionary();
+
+ internal void Add() where TTarget : T
+ {
+ Items[typeof(T)] = typeof(TTarget);
+ }
+ }
+}
diff --git a/zero.Core/Options/ZeroOptions.cs b/zero.Core/Options/ZeroOptions.cs
index 8cbbcf4f..94c487dd 100644
--- a/zero.Core/Options/ZeroOptions.cs
+++ b/zero.Core/Options/ZeroOptions.cs
@@ -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();
}
///
@@ -65,6 +69,20 @@ namespace zero.Core.Options
///
public MapperOptions Mapper { get; private set; }
+
+ ///
+ public TypeOptions Types { get; private set; }
+
+ ///
+ public void Extend() where TTarget : T
+ {
+ Types.Add();
+ }
+
+ public ZeroExtend Extend()
+ {
+ return new ZeroExtend();
+ }
}
@@ -149,10 +167,53 @@ namespace zero.Core.Options
///
MapperOptions Mapper { get; }
+ ///
+ ///
+ ///
+ TypeOptions Types { get; }
+
+ ///
+ void Extend() where TTarget : T;
+
+ ZeroExtend Extend();
///
/// Default settings for the backoffice
///
//IZeroPluginConfiguration Backoffice { get; set; }
}
+
+
+ public class ZeroExtend
+ {
+ public ZeroExtend Use() where TTarget : T
+ {
+ return this;
+ }
+
+ public ZeroExtend Use()
+ where TTarget : T
+ where TRenderer : IRenderer
+ {
+ return this;
+ }
+
+ public ZeroExtend Use()
+ where TTarget : T
+ where TRenderer : IRenderer
+ where TValidator : IValidator
+ {
+ return this;
+ }
+
+
+ public ZeroExtend Use()
+ where TTarget : T
+ where TRenderer : IRenderer
+ where TValidator : IValidator
+ where TMapper : IMapperConfig
+ {
+ return this;
+ }
+ }
}
diff --git a/zero.Core/Renderer/AbstractRenderer.cs b/zero.Core/Renderer/AbstractRenderer.cs
index cd272b87..8e0647e2 100644
--- a/zero.Core/Renderer/AbstractRenderer.cs
+++ b/zero.Core/Renderer/AbstractRenderer.cs
@@ -22,7 +22,7 @@ namespace zero.Core.Renderer
}
- public abstract class AbstractRenderer : IRenderer, IRenderer where T : new()
+ public abstract class AbstractRenderer : IRenderer, IRenderer
{
const string METHOD_FIELD = "field";
diff --git a/zero.Debug/Models/SalesChannel.cs b/zero.Debug/Models/SalesChannel.cs
new file mode 100644
index 00000000..e530925f
--- /dev/null
+++ b/zero.Debug/Models/SalesChannel.cs
@@ -0,0 +1,9 @@
+using zero.Commerce.Entities;
+
+namespace zero.Debug.Models
+{
+ public class SalesChannel : Channel
+ {
+ public string Description { get; set; }
+ }
+}
diff --git a/zero.Debug/Models/SalesChannelRenderer.cs b/zero.Debug/Models/SalesChannelRenderer.cs
new file mode 100644
index 00000000..9501dd4b
--- /dev/null
+++ b/zero.Debug/Models/SalesChannelRenderer.cs
@@ -0,0 +1,46 @@
+using zero.Commerce.Entities;
+using zero.Core.Renderer;
+using zero.Debug.Models;
+
+namespace zero.Commerce.Backoffice
+{
+ public class SalesChannelRenderer : AbstractRenderer
+ {
+ 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;
+ // });
+ //});
+ }
+ }
+}
diff --git a/zero.Debug/Startup.cs b/zero.Debug/Startup.cs
index bebd2461..161c6ef2 100644
--- a/zero.Debug/Startup.cs
+++ b/zero.Debug/Startup.cs
@@ -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();
zero.AddPlugin();
+ zero.WithOptions(opts =>
+ {
+ opts.Extend();
+
+ //IRenderer renderer = (IRenderer)new SalesChannelRenderer();
+ //renderer.
+ //opts.Renderers.Extend();
+ });
+
services.AddMvc();
services.Configure(opts => opts.AutomaticAuthentication = false);
diff --git a/zero.Web.UI/App/editor/editor.vue b/zero.Web.UI/App/editor/editor.vue
index 1bfab858..a0321381 100644
--- a/zero.Web.UI/App/editor/editor.vue
+++ b/zero.Web.UI/App/editor/editor.vue
@@ -6,6 +6,9 @@