Initial Commit
commit
731c3d5f82
|
@ -0,0 +1,43 @@
|
||||||
|
# Autosave files
|
||||||
|
*~
|
||||||
|
|
||||||
|
# build
|
||||||
|
[Oo]bj/
|
||||||
|
[Bb]in/
|
||||||
|
packages/
|
||||||
|
TestResults/
|
||||||
|
|
||||||
|
# globs
|
||||||
|
Makefile.in
|
||||||
|
*.DS_Store
|
||||||
|
*.sln.cache
|
||||||
|
*.suo
|
||||||
|
*.cache
|
||||||
|
*.pidb
|
||||||
|
*.userprefs
|
||||||
|
*.usertasks
|
||||||
|
config.log
|
||||||
|
config.make
|
||||||
|
config.status
|
||||||
|
aclocal.m4
|
||||||
|
install-sh
|
||||||
|
autom4te.cache/
|
||||||
|
*.user
|
||||||
|
*.tar.gz
|
||||||
|
tarballs/
|
||||||
|
test-results/
|
||||||
|
Thumbs.db
|
||||||
|
.vs/
|
||||||
|
|
||||||
|
# Mac bundle stuff
|
||||||
|
*.dmg
|
||||||
|
*.app
|
||||||
|
|
||||||
|
# resharper
|
||||||
|
*_Resharper.*
|
||||||
|
*.Resharper
|
||||||
|
|
||||||
|
# dotCover
|
||||||
|
*.dotCover
|
||||||
|
|
||||||
|
ln.logging
|
|
@ -0,0 +1,39 @@
|
||||||
|
// /**
|
||||||
|
// * File: EmptyProvider.cs
|
||||||
|
// * Author: haraldwolff
|
||||||
|
// *
|
||||||
|
// * This file and it's content is copyrighted by the Author and / or copyright holder.
|
||||||
|
// * Any use wihtout proper permission is illegal and may lead to legal actions.
|
||||||
|
// *
|
||||||
|
// *
|
||||||
|
// **/
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using ln.json;
|
||||||
|
using ln.types.btree;
|
||||||
|
|
||||||
|
namespace ln.manage
|
||||||
|
{
|
||||||
|
public class EmptyProvider : ManagedObjectProvider
|
||||||
|
{
|
||||||
|
public EmptyProvider(String name)
|
||||||
|
: this(name, null) { }
|
||||||
|
public EmptyProvider(String name, ManagedObjectProvider container)
|
||||||
|
: base(null, name, container)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override JSONObject CreateJsonDescriptor()
|
||||||
|
{
|
||||||
|
JSONObject descriptor = base.CreateJsonDescriptor();
|
||||||
|
descriptor["cosmetic"] = true;
|
||||||
|
return descriptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Disable(object o) => throw new NotSupportedException();
|
||||||
|
public override void Enable(object o) => throw new NotSupportedException();
|
||||||
|
public override object GetManagedObject(object uniqueIdentifier) => throw new NotSupportedException();
|
||||||
|
public override ManagedObjectState GetManagedObjectState(object o) => throw new NotSupportedException();
|
||||||
|
public override void RemoveObject(object o) => throw new NotSupportedException();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
// /**
|
||||||
|
// * File: IManagedContainer.cs
|
||||||
|
// * Author: haraldwolff
|
||||||
|
// *
|
||||||
|
// * This file and it's content is copyrighted by the Author and / or copyright holder.
|
||||||
|
// * Any use wihtout proper permission is illegal and may lead to legal actions.
|
||||||
|
// *
|
||||||
|
// *
|
||||||
|
// **/
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
namespace ln.manage
|
||||||
|
{
|
||||||
|
public interface IManagedContainer
|
||||||
|
{
|
||||||
|
IManagedContainer Parent { get; }
|
||||||
|
IEnumerable<IManagedContainer> Children { get; }
|
||||||
|
|
||||||
|
string Name { get; }
|
||||||
|
IEnumerable<PropertyDescriptor> PropertyDescriptors { get; }
|
||||||
|
string IdentityPropertyName { get; }
|
||||||
|
|
||||||
|
IManagedObject[] GetManagedObjects();
|
||||||
|
IManagedObject GetManagedObject(object identity);
|
||||||
|
|
||||||
|
IManagedObject CreateManagedObject();
|
||||||
|
bool DisposeManagedObject(object identity);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
namespace ln.manage
|
||||||
|
{
|
||||||
|
public interface IManagedObject
|
||||||
|
{
|
||||||
|
IManagedContainer Container { get; }
|
||||||
|
object Identity { get; }
|
||||||
|
|
||||||
|
object GetValue(string propertyName);
|
||||||
|
void SetValue(string propertyName, object value);
|
||||||
|
|
||||||
|
bool Enabled { get; set; }
|
||||||
|
bool Valid { get; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,94 @@
|
||||||
|
// /**
|
||||||
|
// * File: Console.cs
|
||||||
|
// * Author: haraldwolff
|
||||||
|
// *
|
||||||
|
// * This file and it's content is copyrighted by the Author and / or copyright holder.
|
||||||
|
// * Any use wihtout proper permission is illegal and may lead to legal actions.
|
||||||
|
// *
|
||||||
|
// *
|
||||||
|
// **/
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Text;
|
||||||
|
using ln.types;
|
||||||
|
using System.Linq;
|
||||||
|
namespace ln.manage
|
||||||
|
{
|
||||||
|
public class ManagedConsole
|
||||||
|
{
|
||||||
|
ManagedRoot ManagedRoot { get; }
|
||||||
|
|
||||||
|
public ManagedConsole(ManagedRoot managedRoot)
|
||||||
|
{
|
||||||
|
ManagedRoot = managedRoot;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public String Export()
|
||||||
|
{
|
||||||
|
MemoryStream memoryStream = new MemoryStream();
|
||||||
|
Export(memoryStream);
|
||||||
|
return Encoding.UTF8.GetString(memoryStream.ToArray());
|
||||||
|
}
|
||||||
|
public void Export(Stream stream)=> Export(stream, ManagedRoot);
|
||||||
|
public void Export(Stream stream, IManagedContainer container) => Export(stream, container, true);
|
||||||
|
public void Export(Stream stream, IManagedContainer container, bool recurse)
|
||||||
|
{
|
||||||
|
string[] containerPath = container.GetContainerPath();
|
||||||
|
string containerPathString = string.Join("/", containerPath);
|
||||||
|
|
||||||
|
foreach (IManagedObject managedObject in container.GetManagedObjects())
|
||||||
|
{
|
||||||
|
if (object.Equals(managedObject.Container, container))
|
||||||
|
{
|
||||||
|
StringBuilder stringBuilder = new StringBuilder();
|
||||||
|
stringBuilder.Append(containerPathString);
|
||||||
|
stringBuilder.Append(" add");
|
||||||
|
foreach (PropertyDescriptor propertyDescriptor in container.PropertyDescriptors)
|
||||||
|
{
|
||||||
|
stringBuilder.AppendFormat(" {0}={1}", propertyDescriptor.PropertyName, ValueToText(managedObject.GetValue(propertyDescriptor.PropertyName)));
|
||||||
|
}
|
||||||
|
stringBuilder.AppendLine();
|
||||||
|
|
||||||
|
if (managedObject.Enabled)
|
||||||
|
{
|
||||||
|
stringBuilder.AppendFormat("{0} enable {1}", containerPathString, managedObject.Identity.ToString());
|
||||||
|
stringBuilder.AppendLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
stream.WriteBytes(Encoding.UTF8.GetBytes(stringBuilder.ToString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (recurse)
|
||||||
|
{
|
||||||
|
foreach (IManagedContainer managedContainer in container.Children)
|
||||||
|
Export(stream, managedContainer, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Execute(String command)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static string ValueToText(object value)
|
||||||
|
{
|
||||||
|
if (value == null)
|
||||||
|
return "";
|
||||||
|
|
||||||
|
Type valueType = value.GetType();
|
||||||
|
if (valueType.IsArray)
|
||||||
|
{
|
||||||
|
object[] array = (object[])value;
|
||||||
|
return string.Join(",", array.Select((e) => ValueToText(e)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return value.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
// /**
|
||||||
|
// * File: ManagedContainerBase.cs
|
||||||
|
// * Author: haraldwolff
|
||||||
|
// *
|
||||||
|
// * This file and it's content is copyrighted by the Author and / or copyright holder.
|
||||||
|
// * Any use wihtout proper permission is illegal and may lead to legal actions.
|
||||||
|
// *
|
||||||
|
// *
|
||||||
|
// **/
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace ln.manage
|
||||||
|
{
|
||||||
|
public abstract class ManagedContainerBase : IManagedContainer
|
||||||
|
{
|
||||||
|
IManagedContainer parent;
|
||||||
|
Dictionary<string, IManagedContainer> containers = new Dictionary<string, IManagedContainer>();
|
||||||
|
|
||||||
|
public ManagedContainerBase(IManagedContainer parent,String name)
|
||||||
|
{
|
||||||
|
Name = name;
|
||||||
|
this.parent = parent;
|
||||||
|
|
||||||
|
if (parent is ManagedContainerBase managedContainerBase)
|
||||||
|
{
|
||||||
|
managedContainerBase.AddContainer(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Name { get; }
|
||||||
|
|
||||||
|
public IManagedContainer Parent => parent;
|
||||||
|
public IEnumerable<IManagedContainer> Children => containers.Values;
|
||||||
|
|
||||||
|
public abstract IEnumerable<PropertyDescriptor> PropertyDescriptors { get; }
|
||||||
|
public abstract string IdentityPropertyName { get; }
|
||||||
|
|
||||||
|
public abstract IManagedObject CreateManagedObject();
|
||||||
|
public abstract bool DisposeManagedObject(object identity);
|
||||||
|
public abstract IManagedObject GetManagedObject(object identity);
|
||||||
|
public abstract IManagedObject[] GetManagedObjects();
|
||||||
|
|
||||||
|
public void AddContainer(IManagedContainer container) => containers.Add(container.Name, container);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace ln.manage
|
||||||
|
{
|
||||||
|
public class UniqueIdentifierAttribute : Attribute
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//public class ManagedForeign<T> : ManagedObject
|
||||||
|
//{
|
||||||
|
// public object POCO { get; }
|
||||||
|
// public new ManagedForeignProvider<T> Provider => base.Provider as ManagedForeignProvider<T>;
|
||||||
|
|
||||||
|
// public override object UniqueID => throw new NotImplementedException();
|
||||||
|
// public override IEnumerable<KeyValuePair<string, object>> Properties => throw new NotImplementedException();
|
||||||
|
|
||||||
|
// ManagedObjectState state = ManagedObjectState.INVALID;
|
||||||
|
// public override ManagedObjectState State => state;
|
||||||
|
|
||||||
|
// public ManagedForeign(ManagedForeignProvider<T> provider, object poco) : base(provider)
|
||||||
|
// {
|
||||||
|
// POCO = poco;
|
||||||
|
// }
|
||||||
|
// public ManagedForeign(ManagedForeignProvider<T> provider) : base(provider)
|
||||||
|
// {
|
||||||
|
// POCO = Activator.CreateInstance(provider.ManagedType);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public override void Update(IEnumerable<KeyValuePair<string, object>> properties) => Provider.Update(this, properties);
|
||||||
|
|
||||||
|
// public override void Enable() => Provider.Enable(this);
|
||||||
|
// public override void Disable() => Provider.Disable(this);
|
||||||
|
// public override void Remove() => Provider.Remove(this);
|
||||||
|
//}
|
||||||
|
}
|
|
@ -0,0 +1,90 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
using System.Reflection;
|
||||||
|
namespace ln.manage
|
||||||
|
{
|
||||||
|
public class ManagedNativeContainer<T> : ManagedContainerBase where T:class,IDisposable
|
||||||
|
{
|
||||||
|
Type managedType;
|
||||||
|
Dictionary<string, NativePropertyDescriptor> propertyDescriptors = new Dictionary<string, NativePropertyDescriptor>();
|
||||||
|
HashSet<ManagedNativeObject<T>> managedNativeObjects = new HashSet<ManagedNativeObject<T>>();
|
||||||
|
|
||||||
|
public ManagedNativeContainer(IManagedContainer parent) :this(parent, typeof(T).Name) { }
|
||||||
|
public ManagedNativeContainer(IManagedContainer parent,String name)
|
||||||
|
:base(parent,name)
|
||||||
|
{
|
||||||
|
managedType = typeof(T);
|
||||||
|
|
||||||
|
foreach (FieldInfo fieldInfo in managedType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
|
||||||
|
{
|
||||||
|
if (fieldInfo.IsPublic || fieldInfo.GetCustomAttribute<PropertyDescriptorAttribute>() != null)
|
||||||
|
{
|
||||||
|
NativePropertyDescriptor nativePropertyDescriptor = new NativePropertyDescriptor(this, fieldInfo);
|
||||||
|
propertyDescriptors.Add(nativePropertyDescriptor.PropertyName,nativePropertyDescriptor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach (PropertyInfo propertyInfo in managedType.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
|
||||||
|
{
|
||||||
|
if (propertyInfo.GetGetMethod().IsPublic || propertyInfo.GetCustomAttribute<PropertyDescriptorAttribute>() != null)
|
||||||
|
{
|
||||||
|
NativePropertyDescriptor nativePropertyDescriptor = new NativePropertyDescriptor(this, propertyInfo);
|
||||||
|
propertyDescriptors.Add(nativePropertyDescriptor.PropertyName, nativePropertyDescriptor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (NativePropertyDescriptor nativePropertyDescriptor in NativePropertyDescriptors)
|
||||||
|
{
|
||||||
|
if (nativePropertyDescriptor.Identity)
|
||||||
|
IdentityDescriptor = nativePropertyDescriptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public IEnumerable<NativePropertyDescriptor> NativePropertyDescriptors => propertyDescriptors.Values;
|
||||||
|
public NativePropertyDescriptor GetNativePropertyDescriptor(string propertyName) => propertyDescriptors[propertyName];
|
||||||
|
public NativePropertyDescriptor IdentityDescriptor { get; }
|
||||||
|
|
||||||
|
public override IEnumerable<PropertyDescriptor> PropertyDescriptors => propertyDescriptors.Values;
|
||||||
|
public override string IdentityPropertyName => IdentityDescriptor.PropertyName;
|
||||||
|
|
||||||
|
public override IManagedObject CreateManagedObject()
|
||||||
|
{
|
||||||
|
ManagedNativeObject<T> managedNativeObject = new ManagedNativeObject<T>(this);
|
||||||
|
managedNativeObjects.Add(managedNativeObject);
|
||||||
|
return managedNativeObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool DisposeManagedObject(object identity) => DisposeManagedObject(GetManagedObject(identity));
|
||||||
|
public bool DisposeManagedObject(ManagedNativeObject<T> managedNativeObject)
|
||||||
|
{
|
||||||
|
if (managedNativeObjects.Contains(managedNativeObject))
|
||||||
|
{
|
||||||
|
managedNativeObject.Enabled = false;
|
||||||
|
managedNativeObjects.Remove(managedNativeObject);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override IManagedObject GetManagedObject(object identity)
|
||||||
|
{
|
||||||
|
foreach (ManagedNativeObject<T> managedNativeObject in managedNativeObjects)
|
||||||
|
{
|
||||||
|
if (Object.Equals(managedNativeObject.Identity, identity))
|
||||||
|
return managedNativeObject;
|
||||||
|
}
|
||||||
|
throw new KeyNotFoundException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override IManagedObject[] GetManagedObjects()
|
||||||
|
{
|
||||||
|
return managedNativeObjects.Cast<IManagedObject>().ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,74 @@
|
||||||
|
// /**
|
||||||
|
// * File: ManagedNativeObject.cs
|
||||||
|
// * Author: haraldwolff
|
||||||
|
// *
|
||||||
|
// * This file and it's content is copyrighted by the Author and / or copyright holder.
|
||||||
|
// * Any use wihtout proper permission is illegal and may lead to legal actions.
|
||||||
|
// *
|
||||||
|
// *
|
||||||
|
// **/
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
namespace ln.manage
|
||||||
|
{
|
||||||
|
public class ManagedNativeObject<T> : IManagedObject where T:class,IDisposable
|
||||||
|
{
|
||||||
|
T instance;
|
||||||
|
Dictionary<string, object> properties = new Dictionary<string, object>();
|
||||||
|
|
||||||
|
public ManagedNativeObject(IManagedContainer container)
|
||||||
|
{
|
||||||
|
Container = container;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IManagedContainer Container { get; }
|
||||||
|
public object Identity => GetValue(Container.IdentityPropertyName);
|
||||||
|
|
||||||
|
public bool Enabled {
|
||||||
|
get => instance != null;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value && !Enabled)
|
||||||
|
{
|
||||||
|
instance = (T)Activator.CreateInstance<T>();
|
||||||
|
Sync();
|
||||||
|
} else if (!value && Enabled)
|
||||||
|
{
|
||||||
|
instance.Dispose();
|
||||||
|
SyncBack();
|
||||||
|
instance = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Valid => throw new NotImplementedException();
|
||||||
|
|
||||||
|
public object GetValue(string propertyName)
|
||||||
|
{
|
||||||
|
return (instance != null) ? (Container as ManagedNativeContainer<T>).GetNativePropertyDescriptor(propertyName).GetValue(instance) : properties[propertyName];
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetValue(string propertyName, object value)
|
||||||
|
{
|
||||||
|
if (instance != null)
|
||||||
|
(Container as ManagedNativeContainer<T>).GetNativePropertyDescriptor(propertyName).SetValue(instance, value);
|
||||||
|
properties[propertyName] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Sync()
|
||||||
|
{
|
||||||
|
foreach (NativePropertyDescriptor nativePropertyDescriptor in (Container as ManagedNativeContainer<T>).NativePropertyDescriptors)
|
||||||
|
{
|
||||||
|
if (properties.ContainsKey(nativePropertyDescriptor.PropertyName))
|
||||||
|
nativePropertyDescriptor.SetValue(instance, properties[nativePropertyDescriptor.PropertyName]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void SyncBack()
|
||||||
|
{
|
||||||
|
foreach (NativePropertyDescriptor nativePropertyDescriptor in (Container as ManagedNativeContainer<T>).NativePropertyDescriptors)
|
||||||
|
{
|
||||||
|
properties[nativePropertyDescriptor.PropertyName] = nativePropertyDescriptor.GetValue(instance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
namespace ln.manage
|
||||||
|
{
|
||||||
|
public enum ManagedObjectState
|
||||||
|
{
|
||||||
|
INVALID = -1, // Object is in invalid state (e.g. invalid property values), implies object being disabled
|
||||||
|
DISABLED = 0, // Object is disabled
|
||||||
|
ENABLED = 1 // Object is enabled
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,129 @@
|
||||||
|
// /**
|
||||||
|
// * File: ManagedObjectDescriptor.cs
|
||||||
|
// * Author: haraldwolff
|
||||||
|
// *
|
||||||
|
// * This file and it's content is copyrighted by the Author and / or copyright holder.
|
||||||
|
// * Any use wihtout proper permission is illegal and may lead to legal actions.
|
||||||
|
// *
|
||||||
|
// *
|
||||||
|
// **/
|
||||||
|
using System;
|
||||||
|
using System.Reflection;
|
||||||
|
using ln.json;
|
||||||
|
using ln.types.net;
|
||||||
|
namespace ln.manage
|
||||||
|
{
|
||||||
|
public class ManagedObjectPropertyDescriptor
|
||||||
|
{
|
||||||
|
public ManagedObjectProvider Provider { get; }
|
||||||
|
public Type ManagedType => Provider.ManagedType;
|
||||||
|
|
||||||
|
public string PropertyName { get; }
|
||||||
|
public Type PropertyType { get; }
|
||||||
|
|
||||||
|
public bool ReadOnly { get; }
|
||||||
|
public string LookupPath { get; }
|
||||||
|
|
||||||
|
Action<object, object> setter;
|
||||||
|
Func<object, object> getter;
|
||||||
|
|
||||||
|
public ManagedObjectPropertyDescriptor(ManagedObjectProvider objectProvider, string propertyName, Type propertyType, bool readOnly, string lookupPath, Func<object, object> getter, Action<object, object> setter)
|
||||||
|
{
|
||||||
|
Provider = objectProvider;
|
||||||
|
PropertyName = propertyName;
|
||||||
|
PropertyType = propertyType;
|
||||||
|
ReadOnly = readOnly;
|
||||||
|
LookupPath = lookupPath;
|
||||||
|
|
||||||
|
this.getter = getter;
|
||||||
|
this.setter = setter;
|
||||||
|
}
|
||||||
|
public ManagedObjectPropertyDescriptor(ManagedObjectProvider objectProvider,string propertyName,Type propertyType,bool readOnly,string lookupPath)
|
||||||
|
:this(objectProvider,propertyName,propertyType,readOnly,lookupPath,null,null)
|
||||||
|
{}
|
||||||
|
public ManagedObjectPropertyDescriptor(ManagedObjectProvider objectProvider, FieldInfo fieldInfo, string lookupPath)
|
||||||
|
: this(objectProvider, fieldInfo.Name, fieldInfo.FieldType, fieldInfo.IsInitOnly, lookupPath, fieldInfo.GetValue, fieldInfo.SetValue)
|
||||||
|
{}
|
||||||
|
public ManagedObjectPropertyDescriptor(ManagedObjectProvider objectProvider, FieldInfo fieldInfo)
|
||||||
|
: this(objectProvider, fieldInfo, null)
|
||||||
|
{}
|
||||||
|
public ManagedObjectPropertyDescriptor(ManagedObjectProvider objectProvider, PropertyInfo propertyInfo, string lookupPath)
|
||||||
|
: this(objectProvider, propertyInfo.Name, propertyInfo.PropertyType, !propertyInfo.CanWrite, lookupPath, propertyInfo.GetValue, propertyInfo.SetValue)
|
||||||
|
{}
|
||||||
|
public ManagedObjectPropertyDescriptor(ManagedObjectProvider objectProvider, PropertyInfo propertyInfo)
|
||||||
|
: this(objectProvider, propertyInfo, null)
|
||||||
|
{}
|
||||||
|
|
||||||
|
public void SetValue(object managedObject, object value) => setter(managedObject, value);
|
||||||
|
public object GetValue(object managedObject) => getter(managedObject);
|
||||||
|
|
||||||
|
public JSONObject CreateJsonDescriptor()
|
||||||
|
{
|
||||||
|
JSONObject descriptor = new JSONObject();
|
||||||
|
|
||||||
|
descriptor["name"] = PropertyName;
|
||||||
|
descriptor["readonly"] = ReadOnly;
|
||||||
|
|
||||||
|
if (typeof(string).Equals(PropertyType))
|
||||||
|
{
|
||||||
|
descriptor["type"] = "string";
|
||||||
|
}
|
||||||
|
else if (typeof(int).Equals(PropertyType))
|
||||||
|
{
|
||||||
|
descriptor["type"] = "int";
|
||||||
|
}
|
||||||
|
else if (typeof(double).Equals(PropertyType))
|
||||||
|
{
|
||||||
|
descriptor["type"] = "double";
|
||||||
|
}
|
||||||
|
else if (typeof(IPv4).Equals(PropertyType))
|
||||||
|
{
|
||||||
|
descriptor["type"] = "ip4";
|
||||||
|
}
|
||||||
|
else if (typeof(IPv6).Equals(PropertyType))
|
||||||
|
{
|
||||||
|
descriptor["type"] = "ip6";
|
||||||
|
}
|
||||||
|
else if (typeof(MAC).Equals(PropertyType))
|
||||||
|
{
|
||||||
|
descriptor["type"] = "mac";
|
||||||
|
}
|
||||||
|
else if (PropertyType.IsEnum)
|
||||||
|
{
|
||||||
|
if (PropertyType.GetCustomAttribute<FlagsAttribute>() != null)
|
||||||
|
{
|
||||||
|
JSONObject type = new JSONObject();
|
||||||
|
string[] names = Enum.GetNames(PropertyType);
|
||||||
|
int[] values = (int[])Enum.GetValues(PropertyType);
|
||||||
|
for (int n = 0; n < names.Length; n++)
|
||||||
|
type[names[n]] = values[n];
|
||||||
|
descriptor["type"] = type;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
JSONArray type = new JSONArray();
|
||||||
|
string[] symbols = Enum.GetNames(PropertyType);
|
||||||
|
foreach (string symbol in symbols)
|
||||||
|
type.Add(symbol);
|
||||||
|
descriptor["type"] = type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (LookupPath != null)
|
||||||
|
{
|
||||||
|
// ToDo: Implement Referenced Objects
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new NotSupportedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return descriptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,203 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
using System.Reflection;
|
||||||
|
using ln.types.btree;
|
||||||
|
using ln.json;
|
||||||
|
using ln.logging;
|
||||||
|
using ln.json.mapping;
|
||||||
|
namespace ln.manage
|
||||||
|
{
|
||||||
|
public abstract class ManagedObjectProvider
|
||||||
|
{
|
||||||
|
public Type ManagedType { get; }
|
||||||
|
|
||||||
|
ManagedObjectProvider container;
|
||||||
|
public ManagedObjectProvider Container {
|
||||||
|
get => container;
|
||||||
|
set {
|
||||||
|
if (Object.Equals(container, this))
|
||||||
|
throw new ArgumentOutOfRangeException(nameof(value));
|
||||||
|
|
||||||
|
container?.RemoveChildProvider(this);
|
||||||
|
container = value;
|
||||||
|
container?.AddChildProvider(this);
|
||||||
|
|
||||||
|
if (!Object.ReferenceEquals(null,container))
|
||||||
|
{
|
||||||
|
List<string> path = new List<string>();
|
||||||
|
fillpath(path);
|
||||||
|
pathlist = PathList.ToArray();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pathlist = new string[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Name { get; private set; }
|
||||||
|
|
||||||
|
public string[] pathlist = new string[0];
|
||||||
|
public string[] PathList => (string[])pathlist.Clone();
|
||||||
|
public string Path => String.Join("/", PathList);
|
||||||
|
|
||||||
|
protected MappingBTree<string, ManagedObjectPropertyDescriptor> propertyDescriptors = new MappingBTree<string, ManagedObjectPropertyDescriptor>((mopd)=>mopd.PropertyName);
|
||||||
|
public virtual IEnumerable<ManagedObjectPropertyDescriptor> PropertyDescriptors => propertyDescriptors.Values;
|
||||||
|
|
||||||
|
public String UniqueIdentifierPropertyName { get; protected set; }
|
||||||
|
|
||||||
|
Dictionary<string, ManagedObjectProvider> children = new Dictionary<string,ManagedObjectProvider>();
|
||||||
|
public IEnumerable<ManagedObjectProvider> Children => children.Values;
|
||||||
|
|
||||||
|
public ManagedObjectProvider(Type type): this(type, type.Name, null) { }
|
||||||
|
public ManagedObjectProvider(Type type, String name) : this(type, name, null) { }
|
||||||
|
public ManagedObjectProvider(Type type, String name, ManagedObjectProvider container) : this(true, type, name, container) { }
|
||||||
|
|
||||||
|
protected ManagedObjectProvider(bool buildPropertyDescriptors,Type type,String name,ManagedObjectProvider container)
|
||||||
|
{
|
||||||
|
ManagedType = type;
|
||||||
|
Name = name;
|
||||||
|
|
||||||
|
Container = container;
|
||||||
|
|
||||||
|
if (buildPropertyDescriptors)
|
||||||
|
BuildPropertyDescriptors();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddChildProvider(ManagedObjectProvider childProvider)
|
||||||
|
{
|
||||||
|
children.Add(childProvider.Name, childProvider);
|
||||||
|
childProvider.container = this;
|
||||||
|
}
|
||||||
|
private void RemoveChildProvider(ManagedObjectProvider childProvider)
|
||||||
|
{
|
||||||
|
if (children.TryGetValue(childProvider.Name, out ManagedObjectProvider child) && Object.Equals(child, childProvider))
|
||||||
|
{
|
||||||
|
children.Remove(childProvider.Name);
|
||||||
|
childProvider.container = null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw new KeyNotFoundException();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void CollectObjects(ISet<Tuple<ManagedObjectProvider, object>> set) { CollectLocalObjects(set); CollectChildObjects(set); }
|
||||||
|
protected virtual void CollectChildObjects(ISet<Tuple<ManagedObjectProvider, object>> set)
|
||||||
|
{
|
||||||
|
foreach (ManagedObjectProvider childProvider in Children)
|
||||||
|
{
|
||||||
|
if (childProvider.ManagedType.IsSubclassOf(ManagedType))
|
||||||
|
{
|
||||||
|
foreach (Tuple<ManagedObjectProvider, object> childObject in childProvider.EnumerateProviderItems())
|
||||||
|
set.Add(childObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
protected virtual void CollectLocalObjects(ISet<Tuple<ManagedObjectProvider, object>> set) { }
|
||||||
|
|
||||||
|
|
||||||
|
public virtual IEnumerable<object> EnumerateItems() => EnumerateProviderItems().Select((arg) => arg.Item2);
|
||||||
|
public virtual IEnumerable<Tuple<ManagedObjectProvider,object>> EnumerateProviderItems()
|
||||||
|
{
|
||||||
|
HashSet<Tuple<ManagedObjectProvider, object>> childObjects = new HashSet<Tuple<ManagedObjectProvider, object>>();
|
||||||
|
CollectObjects(childObjects);
|
||||||
|
return childObjects;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract object GetManagedObject(object uniqueIdentifier);
|
||||||
|
public abstract ManagedObjectState GetManagedObjectState(object o);
|
||||||
|
|
||||||
|
public virtual object CreateManagedObject(IEnumerable<KeyValuePair<string, object>> properties) => throw new NotSupportedException();
|
||||||
|
public virtual object CreateManagedObject() => CreateManagedObject(null);
|
||||||
|
|
||||||
|
public virtual void ChangeObject(object o, IEnumerable<KeyValuePair<string, object>> properties)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
foreach (KeyValuePair<string, object> property in properties)
|
||||||
|
propertyDescriptors[property.Key].SetValue(o, property.Value);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Logging.Log(e);
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void RemoveObject(object o);
|
||||||
|
public abstract void Enable(object o);
|
||||||
|
public abstract void Disable(object o);
|
||||||
|
|
||||||
|
private void fillpath(List<string> path)
|
||||||
|
{
|
||||||
|
if (Container != null)
|
||||||
|
Container.fillpath(path);
|
||||||
|
path.Add(Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void BuildPropertyDescriptors()
|
||||||
|
{
|
||||||
|
if (ManagedType == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
foreach (FieldInfo fieldInfo in ManagedType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
|
||||||
|
{
|
||||||
|
if (fieldInfo.IsPublic || fieldInfo.GetCustomAttribute<ManagedPropertyAttribute>() != null)
|
||||||
|
{
|
||||||
|
propertyDescriptors.Add(new ManagedObjectPropertyDescriptor(this, fieldInfo));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach (PropertyInfo propertyInfo in ManagedType.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
|
||||||
|
{
|
||||||
|
if (propertyInfo.GetMethod.IsPublic || propertyInfo.GetCustomAttribute<ManagedPropertyAttribute>() != null)
|
||||||
|
{
|
||||||
|
propertyDescriptors.Add(new ManagedObjectPropertyDescriptor(this, propertyInfo));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual JSONObject CreateJsonDescriptor()
|
||||||
|
{
|
||||||
|
JSONObject descriptor = new JSONObject();
|
||||||
|
|
||||||
|
descriptor["name"] = Name;
|
||||||
|
descriptor["readonly"] = false;
|
||||||
|
descriptor["cosmetic"] = false;
|
||||||
|
descriptor["hint"] = "";
|
||||||
|
descriptor["key"] = UniqueIdentifierPropertyName;
|
||||||
|
|
||||||
|
JSONObject jproperties = new JSONObject();
|
||||||
|
foreach (ManagedObjectPropertyDescriptor propertyDescriptor in PropertyDescriptors)
|
||||||
|
jproperties[propertyDescriptor.PropertyName] = propertyDescriptor.CreateJsonDescriptor();
|
||||||
|
descriptor["properties"] = jproperties;
|
||||||
|
|
||||||
|
JSONObject jchildren = new JSONObject();
|
||||||
|
foreach (ManagedObjectProvider managedObjectProvider in Children)
|
||||||
|
jchildren[managedObjectProvider.Name] = managedObjectProvider.CreateJsonDescriptor();
|
||||||
|
descriptor["children"] = jchildren;
|
||||||
|
|
||||||
|
return descriptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual JSONObject CreateJsonObject(object o)
|
||||||
|
{
|
||||||
|
if (!ManagedType.Equals(o.GetType()) && !ManagedType.IsSubclassOf(o.GetType()))
|
||||||
|
throw new ArgumentException();
|
||||||
|
|
||||||
|
JSONObject jObject = new JSONObject();
|
||||||
|
jObject["provider"] = this.Path;
|
||||||
|
//jObject["state"] = GetManagedObjectState(o);
|
||||||
|
|
||||||
|
JSONObject jProperties = new JSONObject();
|
||||||
|
foreach (ManagedObjectPropertyDescriptor descriptor in PropertyDescriptors)
|
||||||
|
jProperties[descriptor.PropertyName] = JSONMapper.DefaultMapper.ToJson(descriptor.GetValue(o));
|
||||||
|
jObject["properties"] = jProperties;
|
||||||
|
|
||||||
|
return jObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
using System;
|
||||||
|
using System.Reflection;
|
||||||
|
namespace ln.manage
|
||||||
|
{
|
||||||
|
//public class ManagedProperty
|
||||||
|
//{
|
||||||
|
// public ManagedObjectProvider Provider { get; }
|
||||||
|
|
||||||
|
// public bool ReadOnly { get; }
|
||||||
|
// public string Name { get; }
|
||||||
|
// public Type Type { get; }
|
||||||
|
|
||||||
|
// public bool UniqueIdentifier { get; }
|
||||||
|
|
||||||
|
// public string SourcePath { get; }
|
||||||
|
|
||||||
|
// Func<object,object> getter;
|
||||||
|
// Action<object,object> setter;
|
||||||
|
|
||||||
|
// private ManagedProperty(ManagedObjectProvider provider)
|
||||||
|
// {
|
||||||
|
// Provider = provider;
|
||||||
|
// }
|
||||||
|
// private ManagedProperty(ManagedObjectProvider provider,ManagedPropertyAttribute managedPropertyAttribute)
|
||||||
|
// {
|
||||||
|
// if (managedPropertyAttribute.Group == null)
|
||||||
|
// managedPropertyAttribute.Group = Provider.DefaultName;
|
||||||
|
|
||||||
|
// ReadOnly = managedPropertyAttribute.ReadOnly;
|
||||||
|
// Name = managedPropertyAttribute.Name;
|
||||||
|
// SourcePath = managedPropertyAttribute.SourcePath;
|
||||||
|
// UniqueIdentifier = managedPropertyAttribute.UniqueIdentifier;
|
||||||
|
// }
|
||||||
|
// public ManagedProperty(ManagedObjectProvider provider, FieldInfo fieldInfo)
|
||||||
|
// : this(provider, fieldInfo.GetCustomAttribute<ManagedPropertyAttribute>() ?? new ManagedPropertyAttribute(fieldInfo))
|
||||||
|
// {
|
||||||
|
// Type = fieldInfo.FieldType;
|
||||||
|
// getter = fieldInfo.GetValue;
|
||||||
|
// if (!ReadOnly)
|
||||||
|
// setter = fieldInfo.SetValue;
|
||||||
|
// }
|
||||||
|
// public ManagedProperty(ManagedObjectProvider provider, PropertyInfo propertyInfo)
|
||||||
|
// :this(provider, propertyInfo.GetCustomAttribute<ManagedPropertyAttribute>() ?? new ManagedPropertyAttribute(propertyInfo))
|
||||||
|
// {
|
||||||
|
// Type = propertyInfo.PropertyType;
|
||||||
|
// getter = propertyInfo.GetValue;
|
||||||
|
// if (!ReadOnly)
|
||||||
|
// setter = propertyInfo.SetValue;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public object GetValue(object managedObject) => getter(managedObject);
|
||||||
|
// public void SetValue(object managedObject, object v) => setter(managedObject, v);
|
||||||
|
|
||||||
|
//}
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
using System;
|
||||||
|
using System.Reflection;
|
||||||
|
namespace ln.manage
|
||||||
|
{
|
||||||
|
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
|
||||||
|
public class ManagedPropertyAttribute : Attribute
|
||||||
|
{
|
||||||
|
public string Group { get; set; }
|
||||||
|
|
||||||
|
public bool ReadOnly { get; set; }
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
public bool UniqueIdentifier { get; }
|
||||||
|
|
||||||
|
public string SourcePath { get; set; }
|
||||||
|
|
||||||
|
public ManagedPropertyAttribute()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
public ManagedPropertyAttribute(FieldInfo fieldInfo)
|
||||||
|
{
|
||||||
|
Name = fieldInfo.Name;
|
||||||
|
ReadOnly = fieldInfo.IsInitOnly;
|
||||||
|
}
|
||||||
|
public ManagedPropertyAttribute(PropertyInfo propertyInfo)
|
||||||
|
{
|
||||||
|
Name = propertyInfo.Name;
|
||||||
|
ReadOnly = !propertyInfo.CanWrite;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
// /**
|
||||||
|
// * File: ManagedRoot.cs
|
||||||
|
// * Author: haraldwolff
|
||||||
|
// *
|
||||||
|
// * This file and it's content is copyrighted by the Author and / or copyright holder.
|
||||||
|
// * Any use wihtout proper permission is illegal and may lead to legal actions.
|
||||||
|
// *
|
||||||
|
// *
|
||||||
|
// **/
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Text;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using ln.types;
|
||||||
|
namespace ln.manage
|
||||||
|
{
|
||||||
|
public class ManagedRoot : ManagedContainerBase
|
||||||
|
{
|
||||||
|
public ManagedRoot()
|
||||||
|
:base(null,"")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override IEnumerable<PropertyDescriptor> PropertyDescriptors => new PropertyDescriptor[0];
|
||||||
|
public override string IdentityPropertyName => throw new NotImplementedException();
|
||||||
|
|
||||||
|
public override IManagedObject CreateManagedObject() => throw new NotImplementedException();
|
||||||
|
public override bool DisposeManagedObject(object identity) => throw new NotImplementedException();
|
||||||
|
public override IManagedObject GetManagedObject(object identity) => throw new KeyNotFoundException();
|
||||||
|
public override IManagedObject[] GetManagedObjects() => new IManagedObject[0];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
static class ManagedContainerExtensions
|
||||||
|
{
|
||||||
|
|
||||||
|
public static string[] GetContainerPath(this IManagedContainer container)
|
||||||
|
{
|
||||||
|
List<string> path = new List<string>();
|
||||||
|
Stack<IManagedContainer> stack = new Stack<IManagedContainer>();
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
stack.Push(container);
|
||||||
|
container = container.Parent;
|
||||||
|
} while (container != null);
|
||||||
|
|
||||||
|
while (stack.Count > 0)
|
||||||
|
path.Add(stack.Pop().Name);
|
||||||
|
|
||||||
|
return path.ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
using System;
|
||||||
|
namespace ln.manage
|
||||||
|
{
|
||||||
|
public class ManagerTree
|
||||||
|
{
|
||||||
|
public ManagerTree()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
// /**
|
||||||
|
// * File: NativePropertyDescriptor.cs
|
||||||
|
// * Author: haraldwolff
|
||||||
|
// *
|
||||||
|
// * This file and it's content is copyrighted by the Author and / or copyright holder.
|
||||||
|
// * Any use wihtout proper permission is illegal and may lead to legal actions.
|
||||||
|
// *
|
||||||
|
// *
|
||||||
|
// **/
|
||||||
|
using System;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.ComponentModel;
|
||||||
|
namespace ln.manage
|
||||||
|
{
|
||||||
|
public class NativePropertyDescriptor : PropertyDescriptor
|
||||||
|
{
|
||||||
|
|
||||||
|
public Action<object, object> SetValue { get; }
|
||||||
|
public Func<object, object> GetValue { get; }
|
||||||
|
|
||||||
|
public NativePropertyDescriptor(IManagedContainer managedContainer, FieldInfo fieldInfo)
|
||||||
|
: base(managedContainer, fieldInfo)
|
||||||
|
{
|
||||||
|
GetValue = fieldInfo.GetValue;
|
||||||
|
SetValue = fieldInfo.SetValue;
|
||||||
|
}
|
||||||
|
public NativePropertyDescriptor(IManagedContainer managedContainer, PropertyInfo propertyInfo)
|
||||||
|
: base(managedContainer, propertyInfo)
|
||||||
|
{
|
||||||
|
GetValue = propertyInfo.GetValue;
|
||||||
|
SetValue = propertyInfo.SetValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
|
// Information about this assembly is defined by the following attributes.
|
||||||
|
// Change them to the values specific to your project.
|
||||||
|
|
||||||
|
[assembly: AssemblyTitle("ln.manage")]
|
||||||
|
[assembly: AssemblyDescription("")]
|
||||||
|
[assembly: AssemblyConfiguration("")]
|
||||||
|
[assembly: AssemblyCompany("")]
|
||||||
|
[assembly: AssemblyProduct("")]
|
||||||
|
[assembly: AssemblyCopyright("")]
|
||||||
|
[assembly: AssemblyTrademark("")]
|
||||||
|
[assembly: AssemblyCulture("")]
|
||||||
|
|
||||||
|
// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
|
||||||
|
// The form "{Major}.{Minor}.*" will automatically update the build and revision,
|
||||||
|
// and "{Major}.{Minor}.{Build}.*" will update just the revision.
|
||||||
|
|
||||||
|
[assembly: AssemblyVersion("1.0.*")]
|
||||||
|
|
||||||
|
// The following attributes are used to specify the signing key for the assembly,
|
||||||
|
// if desired. See the Mono documentation for more information about signing.
|
||||||
|
|
||||||
|
//[assembly: AssemblyDelaySign(false)]
|
||||||
|
//[assembly: AssemblyKeyFile("")]
|
|
@ -0,0 +1,120 @@
|
||||||
|
// /**
|
||||||
|
// * File: ManagedObjectDescriptor.cs
|
||||||
|
// * Author: haraldwolff
|
||||||
|
// *
|
||||||
|
// * This file and it's content is copyrighted by the Author and / or copyright holder.
|
||||||
|
// * Any use wihtout proper permission is illegal and may lead to legal actions.
|
||||||
|
// *
|
||||||
|
// *
|
||||||
|
// **/
|
||||||
|
using System;
|
||||||
|
using System.Reflection;
|
||||||
|
using ln.json;
|
||||||
|
using ln.types.net;
|
||||||
|
namespace ln.manage
|
||||||
|
{
|
||||||
|
public class PropertyDescriptorAttribute : Attribute
|
||||||
|
{
|
||||||
|
public string Group { get; set; }
|
||||||
|
public string Alias { get; set; }
|
||||||
|
public bool ReadOnly { get; set; }
|
||||||
|
public string LookupPath { get; set; }
|
||||||
|
|
||||||
|
public bool Identity { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class PropertyDescriptor
|
||||||
|
{
|
||||||
|
public IManagedContainer Container { get; }
|
||||||
|
|
||||||
|
public string PropertyGroup { get; }
|
||||||
|
public string PropertyName { get; }
|
||||||
|
public Type PropertyType { get; }
|
||||||
|
|
||||||
|
public bool ReadOnly { get; }
|
||||||
|
public string LookupPath { get; }
|
||||||
|
|
||||||
|
public bool Identity { get; }
|
||||||
|
|
||||||
|
public PropertyDescriptor(IManagedContainer container, string propertyGoup, string propertyName, Type propertyType, bool readOnly, string lookupPath, bool identity)
|
||||||
|
{
|
||||||
|
Container = container;
|
||||||
|
PropertyGroup = propertyGoup;
|
||||||
|
PropertyName = propertyName;
|
||||||
|
PropertyType = propertyType;
|
||||||
|
ReadOnly = readOnly;
|
||||||
|
LookupPath = lookupPath;
|
||||||
|
Identity = identity;
|
||||||
|
}
|
||||||
|
public PropertyDescriptor(IManagedContainer container, FieldInfo fieldInfo)
|
||||||
|
: this(container, fieldInfo.GetCustomAttribute<PropertyDescriptorAttribute>()?.Group, fieldInfo.GetCustomAttribute<PropertyDescriptorAttribute>()?.Alias ?? fieldInfo.Name, fieldInfo.FieldType, fieldInfo.GetCustomAttribute<PropertyDescriptorAttribute>()?.ReadOnly ?? fieldInfo.IsInitOnly, fieldInfo.GetCustomAttribute<PropertyDescriptorAttribute>()?.LookupPath, fieldInfo.GetCustomAttribute<PropertyDescriptorAttribute>()?.Identity ?? false)
|
||||||
|
{ }
|
||||||
|
public PropertyDescriptor(IManagedContainer container, PropertyInfo propertyInfo)
|
||||||
|
: this(container, propertyInfo.GetCustomAttribute<PropertyDescriptorAttribute>()?.Group, propertyInfo.GetCustomAttribute<PropertyDescriptorAttribute>()?.Alias ?? propertyInfo.Name, propertyInfo.PropertyType, propertyInfo.GetCustomAttribute<PropertyDescriptorAttribute>()?.ReadOnly ?? !propertyInfo.CanWrite, propertyInfo.GetCustomAttribute<PropertyDescriptorAttribute>()?.LookupPath, propertyInfo.GetCustomAttribute<PropertyDescriptorAttribute>()?.Identity ?? false)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
public JSONObject CreateJsonDescriptor()
|
||||||
|
{
|
||||||
|
JSONObject descriptor = new JSONObject();
|
||||||
|
|
||||||
|
descriptor["name"] = PropertyName;
|
||||||
|
descriptor["readonly"] = ReadOnly;
|
||||||
|
|
||||||
|
if (typeof(string).Equals(PropertyType))
|
||||||
|
{
|
||||||
|
descriptor["type"] = "string";
|
||||||
|
}
|
||||||
|
else if (typeof(int).Equals(PropertyType))
|
||||||
|
{
|
||||||
|
descriptor["type"] = "int";
|
||||||
|
}
|
||||||
|
else if (typeof(double).Equals(PropertyType))
|
||||||
|
{
|
||||||
|
descriptor["type"] = "double";
|
||||||
|
}
|
||||||
|
else if (typeof(IPv4).Equals(PropertyType))
|
||||||
|
{
|
||||||
|
descriptor["type"] = "ip4";
|
||||||
|
}
|
||||||
|
else if (typeof(IPv6).Equals(PropertyType))
|
||||||
|
{
|
||||||
|
descriptor["type"] = "ip6";
|
||||||
|
}
|
||||||
|
else if (typeof(MAC).Equals(PropertyType))
|
||||||
|
{
|
||||||
|
descriptor["type"] = "mac";
|
||||||
|
}
|
||||||
|
else if (PropertyType.IsEnum)
|
||||||
|
{
|
||||||
|
if (PropertyType.GetCustomAttribute<FlagsAttribute>() != null)
|
||||||
|
{
|
||||||
|
JSONObject type = new JSONObject();
|
||||||
|
string[] names = Enum.GetNames(PropertyType);
|
||||||
|
int[] values = (int[])Enum.GetValues(PropertyType);
|
||||||
|
for (int n = 0; n < names.Length; n++)
|
||||||
|
type[names[n]] = values[n];
|
||||||
|
descriptor["type"] = type;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
JSONArray type = new JSONArray();
|
||||||
|
string[] symbols = Enum.GetNames(PropertyType);
|
||||||
|
foreach (string symbol in symbols)
|
||||||
|
type.Add(symbol);
|
||||||
|
descriptor["type"] = type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (LookupPath != null)
|
||||||
|
{
|
||||||
|
// ToDo: Implement Referenced Objects
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new NotSupportedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
return descriptor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,70 @@
|
||||||
|
|
||||||
|
Notwendige Operationen
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
- Deskriptoren lesen
|
||||||
|
- Objekte listen
|
||||||
|
- Objekt erstellen
|
||||||
|
- Objekt ändern
|
||||||
|
- Objekt entfernen
|
||||||
|
- Objekt aktivieren
|
||||||
|
- Objekt deaktivieren
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Typen:
|
||||||
|
|
||||||
|
referenz "ref"
|
||||||
|
|
||||||
|
integer "integer"
|
||||||
|
double "double"
|
||||||
|
string "string"
|
||||||
|
|
||||||
|
MAC "mac"
|
||||||
|
IPv4 "ip4"
|
||||||
|
IPv6 "ip6"
|
||||||
|
|
||||||
|
enum ["VALUE1","VALUE2","VALUE3"] // 1-of-N (Value)
|
||||||
|
{ FLAG1: 1, FLAG2: 2, FLAG3: 16} // M-of-N (Bitmask)
|
||||||
|
|
||||||
|
|
||||||
|
PropertyDescriptor
|
||||||
|
------------------
|
||||||
|
|
||||||
|
{
|
||||||
|
name: "aReferencingProperty",
|
||||||
|
type: "ref",
|
||||||
|
readonly: false,
|
||||||
|
lookup: "/a/path/to/valid/objects",
|
||||||
|
hint: "You may choose an object from the list of currently active ones",
|
||||||
|
}
|
||||||
|
{
|
||||||
|
name: "aEnumerationProperty",
|
||||||
|
type: ["NONE","PRIMARY","SECONDARY"],
|
||||||
|
readonly: true,
|
||||||
|
lookup: "/a/path/to/valid/objects",
|
||||||
|
}
|
||||||
|
|
||||||
|
ObjectDescriptor
|
||||||
|
----------------
|
||||||
|
|
||||||
|
{
|
||||||
|
name: "someName", // Name of this type
|
||||||
|
readonly: false, // Objects can be created at this object level
|
||||||
|
cosmetic: false, // This type is not real but to be used for grouping, menu layout, etc.
|
||||||
|
hint: "Some text to descripe this object type",
|
||||||
|
properties: { // Describe all the properties, that are associated with this type
|
||||||
|
aPropertyName: { ... },
|
||||||
|
...
|
||||||
|
},
|
||||||
|
children: { // ObjectDescriptors for ObjectTypes below this object level
|
||||||
|
nameOfSomeType: <ObjectDescriptor>,
|
||||||
|
...
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,81 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup>
|
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
|
<ProjectGuid>{D4E4FD39-6C21-4FCC-8DE0-6494FBE82CEA}</ProjectGuid>
|
||||||
|
<OutputType>Library</OutputType>
|
||||||
|
<RootNamespace>ln.manage</RootNamespace>
|
||||||
|
<AssemblyName>ln.manage</AssemblyName>
|
||||||
|
<TargetFrameworkVersion>v4.7</TargetFrameworkVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<Optimize>false</Optimize>
|
||||||
|
<OutputPath>bin\Debug</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<ConsolePause>false</ConsolePause>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<OutputPath>bin\Release</OutputPath>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<ConsolePause>false</ConsolePause>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="System" />
|
||||||
|
<Reference Include="nunit.framework">
|
||||||
|
<Package>nunit</Package>
|
||||||
|
</Reference>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
<Compile Include="ManagerTree.cs" />
|
||||||
|
<Compile Include="ManagedObjectProvider.cs" />
|
||||||
|
<Compile Include="ManagedProperty.cs" />
|
||||||
|
<Compile Include="ManagedPropertyAttribute.cs" />
|
||||||
|
<Compile Include="IManagedObject.cs" />
|
||||||
|
<Compile Include="ManagedObject.cs" />
|
||||||
|
<Compile Include="ManagedForeign.cs" />
|
||||||
|
<Compile Include="ManagedNativeContainer.cs" />
|
||||||
|
<Compile Include="EmptyProvider.cs" />
|
||||||
|
<Compile Include="ManagedObjectPropertyDescriptor.cs" />
|
||||||
|
<Compile Include="test\LNManageTests.cs" />
|
||||||
|
<Compile Include="provider\CurrentThreadsProvider.cs" />
|
||||||
|
<Compile Include="IManagedContainer.cs" />
|
||||||
|
<Compile Include="PropertyDescriptor.cs" />
|
||||||
|
<Compile Include="ManagedRoot.cs" />
|
||||||
|
<Compile Include="ManagedContainerBase.cs" />
|
||||||
|
<Compile Include="ManagedNativeObject.cs" />
|
||||||
|
<Compile Include="NativePropertyDescriptor.cs" />
|
||||||
|
<Compile Include="ManagedConsole.cs" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\ln.types\ln.types.csproj">
|
||||||
|
<Project>{8D9AB9A5-E513-4BA7-A450-534F6456BF28}</Project>
|
||||||
|
<Name>ln.types</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="..\ln.json\ln.json.csproj">
|
||||||
|
<Project>{D9342117-3249-4D8B-87C9-51A50676B158}</Project>
|
||||||
|
<Name>ln.json</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="..\ln.logging\ln.logging.csproj">
|
||||||
|
<Project>{D471A566-9FB6-41B2-A777-3C32874ECD0E}</Project>
|
||||||
|
<Name>ln.logging</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="doc\" />
|
||||||
|
<Folder Include="test\" />
|
||||||
|
<Folder Include="provider\" />
|
||||||
|
<Folder Include="container\" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="doc\notes.txt" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||||
|
</Project>
|
|
@ -0,0 +1,35 @@
|
||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio 15
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ln.manage", "ln.manage.csproj", "{D4E4FD39-6C21-4FCC-8DE0-6494FBE82CEA}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ln.json", "..\ln.json\ln.json.csproj", "{D9342117-3249-4D8B-87C9-51A50676B158}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ln.types", "..\ln.types\ln.types.csproj", "{8D9AB9A5-E513-4BA7-A450-534F6456BF28}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ln.logging", "..\ln.logging\ln.logging.csproj", "{D471A566-9FB6-41B2-A777-3C32874ECD0E}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{D4E4FD39-6C21-4FCC-8DE0-6494FBE82CEA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{D4E4FD39-6C21-4FCC-8DE0-6494FBE82CEA}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{D4E4FD39-6C21-4FCC-8DE0-6494FBE82CEA}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{D4E4FD39-6C21-4FCC-8DE0-6494FBE82CEA}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{D9342117-3249-4D8B-87C9-51A50676B158}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{D9342117-3249-4D8B-87C9-51A50676B158}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{D9342117-3249-4D8B-87C9-51A50676B158}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{D9342117-3249-4D8B-87C9-51A50676B158}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{8D9AB9A5-E513-4BA7-A450-534F6456BF28}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{8D9AB9A5-E513-4BA7-A450-534F6456BF28}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{8D9AB9A5-E513-4BA7-A450-534F6456BF28}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{8D9AB9A5-E513-4BA7-A450-534F6456BF28}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{D471A566-9FB6-41B2-A777-3C32874ECD0E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{D471A566-9FB6-41B2-A777-3C32874ECD0E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{D471A566-9FB6-41B2-A777-3C32874ECD0E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{D471A566-9FB6-41B2-A777-3C32874ECD0E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
|
@ -0,0 +1,99 @@
|
||||||
|
// /**
|
||||||
|
// * File: CurrentThreadsProvider.cs
|
||||||
|
// * Author: haraldwolff
|
||||||
|
// *
|
||||||
|
// * This file and it's content is copyrighted by the Author and / or copyright holder.
|
||||||
|
// * Any use wihtout proper permission is illegal and may lead to legal actions.
|
||||||
|
// *
|
||||||
|
// *
|
||||||
|
// **/
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
|
namespace ln.manage.provider
|
||||||
|
{
|
||||||
|
public class CurrentThreadsProvider : ManagedObjectProvider
|
||||||
|
{
|
||||||
|
Dictionary<int, ManagedThread> managedThreads = new Dictionary<int, ManagedThread>();
|
||||||
|
|
||||||
|
public CurrentThreadsProvider(ManagedObjectProvider container)
|
||||||
|
:base(typeof(ManagedThread),"threads",container)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override IEnumerable<object> EnumerateItems()
|
||||||
|
{
|
||||||
|
HashSet<ManagedThread> currentThreads = new HashSet<ManagedThread>(managedThreads.Values);
|
||||||
|
|
||||||
|
foreach (ProcessThread processThread in Process.GetCurrentProcess().Threads)
|
||||||
|
{
|
||||||
|
if (managedThreads.TryGetValue(processThread.Id,out ManagedThread managedThread))
|
||||||
|
{
|
||||||
|
currentThreads.Remove(managedThread);
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
managedThread = new ManagedThread(this, processThread);
|
||||||
|
managedThreads.Add(managedThread.Id, managedThread);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (ManagedThread managedThread in currentThreads)
|
||||||
|
managedThreads.Remove(managedThread.Id);
|
||||||
|
|
||||||
|
return managedThreads.Values;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override object GetManagedObject(object uniqueIdentifier)
|
||||||
|
{
|
||||||
|
int id = (int)uniqueIdentifier;
|
||||||
|
if (!managedThreads.ContainsKey(id))
|
||||||
|
EnumerateItems();
|
||||||
|
return managedThreads[id];
|
||||||
|
}
|
||||||
|
|
||||||
|
public override ManagedObjectState GetManagedObjectState(object o) => (o as ManagedThread).State;
|
||||||
|
|
||||||
|
public override void Disable(object o) => throw new NotSupportedException();
|
||||||
|
public override void Enable(object o) => throw new NotSupportedException();
|
||||||
|
public override void RemoveObject(object o) => throw new NotSupportedException();
|
||||||
|
|
||||||
|
public class ManagedThread
|
||||||
|
{
|
||||||
|
ProcessThread thread;
|
||||||
|
|
||||||
|
public ManagedThread(CurrentThreadsProvider provider,ProcessThread thread)
|
||||||
|
{
|
||||||
|
this.thread = thread;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal ManagedObjectState State
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
switch (thread.ThreadState)
|
||||||
|
{
|
||||||
|
case System.Diagnostics.ThreadState.Running:
|
||||||
|
case System.Diagnostics.ThreadState.Wait:
|
||||||
|
return ManagedObjectState.ENABLED;
|
||||||
|
case System.Diagnostics.ThreadState.Initialized:
|
||||||
|
case System.Diagnostics.ThreadState.Ready:
|
||||||
|
case System.Diagnostics.ThreadState.Standby:
|
||||||
|
case System.Diagnostics.ThreadState.Terminated:
|
||||||
|
case System.Diagnostics.ThreadState.Transition:
|
||||||
|
return ManagedObjectState.DISABLED;
|
||||||
|
default:
|
||||||
|
return ManagedObjectState.INVALID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Id => thread.Id;
|
||||||
|
public int StartAddress => thread.StartAddress.ToInt32();
|
||||||
|
public double UserTime => thread.UserProcessorTime.TotalSeconds;
|
||||||
|
public double TotalTime => thread.TotalProcessorTime.TotalSeconds;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
using NUnit.Framework;
|
||||||
|
using System;
|
||||||
|
using ln.manage.provider;
|
||||||
|
namespace ln.manage.test
|
||||||
|
{
|
||||||
|
public class Item
|
||||||
|
{
|
||||||
|
[UniqueIdentifier]
|
||||||
|
public string ItemCode { get; set; }
|
||||||
|
public string ItemName { get; set; }
|
||||||
|
public string ItemDescription { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Work : Item
|
||||||
|
{
|
||||||
|
public int AccTimePrec { get; set; }
|
||||||
|
public int AccTimeMin { get; set; }
|
||||||
|
|
||||||
|
public int PricePerTimeUnit { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Article : Item
|
||||||
|
{
|
||||||
|
public int Price { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[TestFixture()]
|
||||||
|
public class LNManageTests
|
||||||
|
{
|
||||||
|
[Test()]
|
||||||
|
public void TestCase()
|
||||||
|
{
|
||||||
|
ManagedObjectProvider pRoot = new EmptyProvider("ManageTest");
|
||||||
|
Console.WriteLine("root: {0}", pRoot.CreateJsonDescriptor());
|
||||||
|
|
||||||
|
ManagedObjectProvider pSystem = new EmptyProvider("System",pRoot);
|
||||||
|
ManagedObjectProvider pThreads = new CurrentThreadsProvider(pSystem);
|
||||||
|
|
||||||
|
Console.WriteLine("root+work+articles: {0}", pRoot.CreateJsonDescriptor());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue