Added the Voile Commons.

This commit is contained in:
feyris-tan 2026-01-20 16:59:40 +01:00
parent d4335858a1
commit 0b851165d8
20 changed files with 385 additions and 3 deletions

5
.gitignore vendored
View File

@ -22,3 +22,8 @@
/Voile.Storage.Oracle/obj
/Voile.Storage.Postgresql/obj
/Voile.Storage.SqlServer/obj
/Voile.Common/bin
/Voile.Common/obj
/Voile.Common.Tests/bin
/Voile.Common.Tests/obj
/.idea

View File

@ -0,0 +1,51 @@
using Voile.Common.Configuration;
namespace Voile.Common.Tests.DemoAssets;
public class AutoconfigSource : IConfigurationSource
{
public bool ReadValue(string category, string key, bool defaultVaule)
{
return true;
}
public object ReadValue(string category, string key, float defaultVaule)
{
throw new NotImplementedException();
}
public int ReadValue(string category, string key, int defaultVaule)
{
return 2;
}
public string ReadValue(string category, string key, string defaultVaule)
{
return "Three";
}
public void WriteValue(string category, string key, bool value)
{
throw new NotImplementedException();
}
public void WriteValue(string category, string key, long value)
{
throw new NotImplementedException();
}
public void WriteValue(string category, string key, int value)
{
throw new NotImplementedException();
}
public void WriteValue(string category, string key, string value)
{
throw new NotImplementedException();
}
public void WriteValue(string category, string key, float value)
{
throw new NotImplementedException();
}
}

View File

@ -0,0 +1,15 @@
using Voile.Common.Reflection;
namespace Voile.Common.Tests.DemoAssets;
public class AutoconfigurableObject
{
[Autoconfigurable]
public bool BooleanValue { get; set; }
[Autoconfigurable]
public int IntegerValue { get; set; }
[Autoconfigurable]
public string StringValue { get; set; }
}

View File

@ -0,0 +1,16 @@
namespace Voile.Common.Configuration;
public interface IConfigurationSource
{
public bool ReadValue(string category, string key, bool defaultVaule);
public object ReadValue(string category, string key, float defaultVaule);
public int ReadValue(string category, string key, int defaultVaule);
public string ReadValue(string category, string key, string defaultVaule);
public void WriteValue(string category, string key, bool value);
public void WriteValue(string category, string key, long value);
public void WriteValue(string category, string key, int value);
public void WriteValue(string category, string key, string value);
public void WriteValue(string category, string key, float value);
}

View File

@ -0,0 +1,12 @@
namespace Voile.Common.DRM;
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = true)]
public sealed class NeedsEntitlementAttribute : Attribute
{
public NeedsEntitlementAttribute(string guid)
{
this.Guid = Guid.Parse(guid);
}
public Guid Guid { get; private set; }
}

View File

@ -0,0 +1,6 @@
namespace Voile.Common.Logging;
public interface IVoileLogSink
{
void OnLogMessage(VoileLogMessage message);
}

View File

@ -0,0 +1,23 @@
namespace Voile.Common.Logging.Sinks;
public class VoileConsoleSink : IVoileLogSink
{
private static VoileConsoleSink _instance;
public static VoileConsoleSink GetInstance()
{
if (_instance == null)
{
_instance = new VoileConsoleSink();
}
return _instance;
}
private VoileConsoleSink()
{}
public void OnLogMessage(VoileLogMessage message)
{
Console.WriteLine(String.Format("{0} {1} {2} - {3}", message.Timestamp.ToString(), message.Level.ToString(), message.SourceName, message.Message));
}
}

View File

@ -0,0 +1,13 @@
namespace Voile.Common.Logging;
public enum VoileLogLevel : int
{
OFF = 0,
FATAL = 100,
ERROR = 200,
WARN = 300,
INFO = 400,
DEBUG = 500,
TRACE = 600,
ALL = Int32.MaxValue
}

View File

@ -0,0 +1,67 @@
namespace Voile.Common.Logging;
public class VoileLogManager
{
private VoileLogManager()
{
}
private static VoileLogManager instance;
public static VoileLogManager GetInstance()
{
if (instance == null)
{
instance = new VoileLogManager();
}
return instance;
}
private List<IVoileLogSink> _sinks;
private Dictionary<string, VoileLogger> _producers;
public void AddSink(IVoileLogSink sink)
{
if (_sinks == null)
_sinks = new List<IVoileLogSink>();
_sinks.Add(sink);
}
public void RemoveSink(IVoileLogSink sink)
{
if (_sinks == null)
return;
else
_sinks.Remove(sink);
}
public static VoileLogger GetLogger(Type type)
{
return GetLogger(type.Name);
}
public static VoileLogger GetLogger(string name)
{
VoileLogManager instance = GetInstance();
if (instance._producers == null)
instance._producers = new Dictionary<string, VoileLogger>();
if (instance._producers.ContainsKey(name))
return instance._producers[name];
VoileLogger child = new VoileLogger(name, instance);
instance._producers.Add(name, child);
return child;
}
internal void ProcessMessage(VoileLogMessage produced)
{
if (_sinks == null)
return;
foreach (IVoileLogSink sink in _sinks)
{
sink.OnLogMessage(produced);
}
}
}

View File

@ -0,0 +1,17 @@
namespace Voile.Common.Logging;
public class VoileLogMessage
{
public VoileLogMessage(DateTime timestamp, VoileLogLevel level, string sourceName, string message)
{
Timestamp = timestamp;
Level = level;
SourceName = sourceName;
Message = message;
}
public DateTime Timestamp { get; private set; }
public VoileLogLevel Level { get; private set; }
public string SourceName { get; private set; }
public string Message { get; private set; }
}

View File

@ -0,0 +1,39 @@
namespace Voile.Common.Logging;
public class VoileLogger
{
private readonly string _name;
private readonly VoileLogManager _manager;
internal VoileLogger(string name, VoileLogManager manager)
{
_name = name;
_manager = manager;
}
public void Log(VoileLogLevel level, string message)
{
VoileLogMessage produced = new VoileLogMessage(DateTime.Now, level, _name, message);
_manager.ProcessMessage(produced);
}
public void Info(string message, params object[] args)
{
Log(VoileLogLevel.INFO, String.Format(message, args));
}
public void Warn(string message, params object[] args)
{
Log(VoileLogLevel.WARN, String.Format(message, args));
}
public void Error(string message, params object[] args)
{
Log(VoileLogLevel.ERROR, String.Format(message, args));
}
public void Debug(string message, params object[] args)
{
Log(VoileLogLevel.DEBUG, String.Format(message, args));
}
}

View File

@ -0,0 +1,12 @@
namespace Voile.Common.Reflection;
[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)]
public sealed class AutoconfigurableAttribute : Attribute
{
// See the attribute guidelines at
// http://go.microsoft.com/fwlink/?LinkId=85236
public AutoconfigurableAttribute()
{
}
}

View File

@ -0,0 +1,56 @@
using System.Reflection;
using Voile.Common.Configuration;
using Voile.Common.Logging;
namespace Voile.Common.Reflection;
public class Autoconfigurer
{
private static Autoconfigurer instance;
private static VoileLogger logger = VoileLogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name);
private Autoconfigurer()
{
}
public static Autoconfigurer GetInstance()
{
if (instance == null)
{
instance = new Autoconfigurer();
}
return instance;
}
public void Autoconfigure(IConfigurationSource source, string categoryName, object target)
{
Type type = target.GetType();
PropertyInfo[] propertyInfos = type.GetProperties();
foreach (PropertyInfo propertyInfo in propertyInfos)
{
AutoconfigurableAttribute? autoconfigurableAttribute = propertyInfo.GetCustomAttribute<AutoconfigurableAttribute>();
if (autoconfigurableAttribute == null)
continue;
Type propertyInfoPropertyType = propertyInfo.PropertyType;
switch (propertyInfoPropertyType.Name)
{
case "Boolean":
bool booleanValue = source.ReadValue(categoryName, propertyInfo.Name, false);
propertyInfo.SetValue(target, booleanValue, null);
break;
case "Int32":
int intValue = source.ReadValue(categoryName, propertyInfo.Name, 0);
propertyInfo.SetValue(target, intValue, null);
break;
case "String":
string stringValue = source.ReadValue(categoryName, propertyInfo.Name, string.Empty);
propertyInfo.SetValue(target, stringValue, null);
break;
default:
logger.Error("Don't know how to autoconfigure an {0}.", propertyInfoPropertyType.Name);
continue;
}
}
}
}

View File

@ -0,0 +1,10 @@
namespace Voile.Common.Reflection;
[AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = false)]
public sealed class IncompleteAttribute : Attribute
{
public IncompleteAttribute()
{
}
}

View File

@ -0,0 +1,10 @@
namespace Voile.Common.Reflection;
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
public sealed class VoilePluginAttribute : Attribute
{
public VoilePluginAttribute()
{
}
}

View File

@ -0,0 +1,16 @@
namespace Voile.Common;
public class VoileException : Exception
{
public VoileException()
{
}
public VoileException(string message) : base(message)
{
}
public VoileException(string message, Exception inner) : base(message, inner)
{
}
}

View File

@ -6,4 +6,8 @@
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Voile.Common\Voile.Common.csproj" />
</ItemGroup>
</Project>

View File

@ -6,4 +6,8 @@
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Voile.Common\Voile.Common.csproj" />
</ItemGroup>
</Project>

View File

@ -6,4 +6,8 @@
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Voile.Common\Voile.Common.csproj" />
</ItemGroup>
</Project>

View File

@ -1,8 +1,10 @@
<Solution>
<Project Path="../skyscraper8/skyscraper8/skyscraper8.csproj" />
<Project Path="Sophia.Net.DRM/Sophia.Net.DRM.csproj" />
<Project Path="Voile.Storage.Oracle/Voile.Storage.Oracle.csproj" Id="9e1745dd-beb2-409d-bd40-73e3a975f43d" />
<Project Path="Voile.Storage.Postgresql/Voile.Storage.Postgresql.csproj" Id="97e3d78d-bc7a-45ad-8a51-bf342703f3c1" />
<Project Path="Voile.Storage.SqlServer/Voile.Storage.SqlServer.csproj" Id="5409177f-bce3-45b2-b28d-bc2be300b4e9" />
<Project Path="Voile.Common.Tests\Voile.Common.Tests.csproj" Type="Classic C#" />
<Project Path="Voile.Common\Voile.Common.csproj" Type="Classic C#" />
<Project Path="Voile.Storage.Oracle/Voile.Storage.Oracle.csproj" />
<Project Path="Voile.Storage.Postgresql/Voile.Storage.Postgresql.csproj" />
<Project Path="Voile.Storage.SqlServer/Voile.Storage.SqlServer.csproj" />
<Project Path="Voile/Voile.csproj" />
</Solution>