1. CollectionFactory - create ienumerable and array in runtime
2. Configuration.Bind - map config to custom config class
pull/1/head
Ogoun 5 years ago
parent 5ccb2120bf
commit 6a2a09514b

@ -0,0 +1,21 @@
using System.Collections.Generic;
namespace ConfigurationTests
{
public class AppConfig
{
public string Url;
public int BatchSize;
public IEnumerable<string> Sheme;
public IEnumerable<int> Port;
public ServiceConfig Service;
}
public class ServiceConfig
{
public string AppName;
public string AppKey;
public string ServiceGroup;
public string ServiceType;
}
}

@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\ZeroLevel\ZeroLevel.csproj" />
</ItemGroup>
<ItemGroup>
<None Update="config.ini">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>

@ -0,0 +1,27 @@
using System;
using ZeroLevel;
namespace ConfigurationTests
{
class Program
{
static void Main(string[] args)
{
var config = Configuration.ReadFromIniFile("config.ini").Bind<AppConfig>();
Console.WriteLine(config.Url);
Console.WriteLine(config.BatchSize);
Console.WriteLine("Ports");
foreach (var port in config.Port)
{
Console.WriteLine($"\t{port}");
}
Console.WriteLine("Shemes");
foreach (var sheme in config.Sheme)
{
Console.WriteLine($"\t{sheme}");
}
Console.ReadKey();
}
}
}

@ -0,0 +1,14 @@
url=https://habr.ru
batchSize=1000
sheme=socks
sheme=http
sheme=https
port=80
port=90
port=8800
[service]
AppName=TestApp
AppKey=test.app
ServiceGroup=seo
ServiceType=site

@ -31,6 +31,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ZeroLevel.SQL", "ZeroLevel.
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZeroNetworkMonitor", "ZeroNetworkMonitor\ZeroNetworkMonitor.csproj", "{EECF6EA0-6D9C-4B69-9CA3-23357C04B84C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConfigurationTests", "ConfigurationTests\ConfigurationTests.csproj", "{E37785CE-E75A-49FB-B17F-16A0F2C6D656}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -185,6 +187,18 @@ Global
{EECF6EA0-6D9C-4B69-9CA3-23357C04B84C}.Release|x64.Build.0 = Release|Any CPU
{EECF6EA0-6D9C-4B69-9CA3-23357C04B84C}.Release|x86.ActiveCfg = Release|Any CPU
{EECF6EA0-6D9C-4B69-9CA3-23357C04B84C}.Release|x86.Build.0 = Release|Any CPU
{E37785CE-E75A-49FB-B17F-16A0F2C6D656}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E37785CE-E75A-49FB-B17F-16A0F2C6D656}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E37785CE-E75A-49FB-B17F-16A0F2C6D656}.Debug|x64.ActiveCfg = Debug|Any CPU
{E37785CE-E75A-49FB-B17F-16A0F2C6D656}.Debug|x64.Build.0 = Debug|Any CPU
{E37785CE-E75A-49FB-B17F-16A0F2C6D656}.Debug|x86.ActiveCfg = Debug|Any CPU
{E37785CE-E75A-49FB-B17F-16A0F2C6D656}.Debug|x86.Build.0 = Debug|Any CPU
{E37785CE-E75A-49FB-B17F-16A0F2C6D656}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E37785CE-E75A-49FB-B17F-16A0F2C6D656}.Release|Any CPU.Build.0 = Release|Any CPU
{E37785CE-E75A-49FB-B17F-16A0F2C6D656}.Release|x64.ActiveCfg = Release|Any CPU
{E37785CE-E75A-49FB-B17F-16A0F2C6D656}.Release|x64.Build.0 = Release|Any CPU
{E37785CE-E75A-49FB-B17F-16A0F2C6D656}.Release|x86.ActiveCfg = Release|Any CPU
{E37785CE-E75A-49FB-B17F-16A0F2C6D656}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

@ -0,0 +1,89 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using ZeroLevel.Services.Invokation;
namespace ZeroLevel.Services.Collections
{
public interface ICollectionBuilder
{
void Append(object item);
IEnumerable Complete();
}
public interface IArrayBuilder
{
void Set(object item, int index);
object Complete();
}
public class CollectionFactory
{
public static ICollectionBuilder Create<T>() => Create(typeof(T));
public static ICollectionBuilder Create(Type type)
{
return new IEnumerableBuilder(type);
}
public static IArrayBuilder CreateArray<T>(int count) => CreateArray(typeof(T), count);
public static IArrayBuilder CreateArray(Type type, int count)
{
return new ArrayBuilder(type, count);
}
private class IEnumerableBuilder
: ICollectionBuilder
{
private readonly IInvokeWrapper _wrapper;
private readonly Invoker _insert;
private readonly object _instance;
public IEnumerableBuilder(Type entityType)
{
_wrapper = InvokeWrapper.Create();
var genericType = typeof(List<>);
var instanceType = genericType.MakeGenericType(new Type[] { entityType });
_instance = Activator.CreateInstance(instanceType);
var insert_key = _wrapper.Configure(instanceType, "Add").Single();
_insert = _wrapper.GetInvoker(insert_key);
}
public void Append(object item)
{
_insert.Invoke(_instance, new object[] { item });
}
public IEnumerable Complete()
{
return (IEnumerable)_instance;
}
}
private class ArrayBuilder
: IArrayBuilder
{
private readonly IInvokeWrapper _wrapper;
private readonly Invoker _insert;
private readonly object _instance;
public ArrayBuilder(Type entityType, int count)
{
_instance = Array.CreateInstance(entityType, count);
}
public void Set(object item, int index)
{
((Array)_instance).SetValue(item, index);
}
public object Complete()
{
return _instance;
}
}
}
}

@ -2,6 +2,9 @@
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using ZeroLevel.Services.Collections;
using ZeroLevel.Services.ObjectMapping;
using ZeroLevel.Services.Reflection;
using ZeroLevel.Services.Serialization;
@ -459,5 +462,69 @@ namespace ZeroLevel.Services.Config
config.Append(key, this[key]);
}
}
public T Bind<T>()
{
var mapper = TypeMapper.Create<T>(true);
var instance = (T)TypeHelpers.CreateInitialState(typeof(T));
mapper.TraversalMembers(member =>
{
if (Contains(member.Name))
{
int count = Count(member.Name);
switch (count)
{
case 0: return;
case 1: // field
member.Setter(instance, First(member.Name));
break;
default: // array, or first
if (TypeHelpers.IsArray(member.ClrType))
{
var itemType = member.ClrType.GetElementType();
if (itemType == typeof(string))
{
var array = Items(member.Name).ToArray();
member.Setter(instance, array);
}
else
{
var arrayBuilder = CollectionFactory.CreateArray(itemType, count);
int index = 0;
foreach (var item in Items(member.Name))
{
arrayBuilder.Set(StringToTypeConverter.TryConvert(item, itemType), index);
index++;
}
member.Setter(instance, arrayBuilder.Complete());
}
}
else if (TypeHelpers.IsEnumerable(member.ClrType))
{
var itemType = member.ClrType.GenericTypeArguments.First();
if (itemType == typeof(string))
{
member.Setter(instance, Items(member.Name));
}
else
{
var collectionBuilder = CollectionFactory.Create(itemType);
foreach (var item in Items(member.Name))
{
collectionBuilder.Append(StringToTypeConverter.TryConvert(item, itemType));
}
member.Setter(instance, collectionBuilder.Complete());
}
}
else
{
member.Setter(instance, First(member.Name));
}
break;
}
}
});
return instance;
}
}
}

@ -257,5 +257,10 @@ namespace ZeroLevel.Services.Config
set[sectionName].CopyTo(section);
}
}
public T Bind<T>()
{
return default;
}
}
}

@ -141,5 +141,7 @@ namespace ZeroLevel
#endregion Create, Clean, Delete
void CopyTo(IConfiguration config);
T Bind<T>();
}
}

@ -91,5 +91,7 @@ namespace ZeroLevel
void Merge(IConfigurationSet set);
#endregion Methods
T Bind<T>();
}
}

@ -186,6 +186,11 @@ namespace ZeroLevel.Services.Reflection
return FormatterServices.GetUninitializedObject(type);
}
public static Type GetArrayType(Type elementType)
{
return elementType.MakeArrayType();
}
public static object CreateNonInitializedInstance(Type type)
{
if (type == null)

Loading…
Cancel
Save

Powered by TurnKey Linux.