diff --git a/README.md b/README.md index 1696aa3..ad3101c 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ **使用Nuget安装** ```PM -Install-Package CatLib.Core -Version 1.2.11 +Install-Package CatLib.Core -Version 1.2.12 ``` **直接下载发布版本** diff --git a/src/CatLib.Core.NetStandard/CatLib.Core.NetStandard.csproj b/src/CatLib.Core.NetStandard/CatLib.Core.NetStandard.csproj index da6387f..8922f1d 100644 --- a/src/CatLib.Core.NetStandard/CatLib.Core.NetStandard.csproj +++ b/src/CatLib.Core.NetStandard/CatLib.Core.NetStandard.csproj @@ -63,6 +63,10 @@ + + + + @@ -133,6 +137,7 @@ + diff --git a/src/CatLib.Core.Tests/CatLib/ApplicationTests.cs b/src/CatLib.Core.Tests/CatLib/ApplicationTests.cs index db48dbc..fb1595e 100644 --- a/src/CatLib.Core.Tests/CatLib/ApplicationTests.cs +++ b/src/CatLib.Core.Tests/CatLib/ApplicationTests.cs @@ -64,6 +64,7 @@ public void Register() } [TestMethod] + [ExpectedException(typeof(RuntimeException))] public void RepeatInitTest() { var app = MakeApplication(); @@ -106,6 +107,98 @@ public void NoBootstrapInit() }); } + public class StopBootstrap : IBootstrap + { + public string value = string.Empty; + public bool stop = false; + public void Bootstrap() + { + value = "bootstrap"; + } + } + + [TestMethod] + public void TestStopBootstrap() + { + var bootstrapStopped = new StopBootstrap() { stop = true }; + var bootstrapNotStopped = new StopBootstrap(); + var application = Application.New(); + application.Listen(ApplicationEvents.Bootstrapping, (b) => + { + if (((StopBootstrap)b).stop) + { + return false; + } + return null; + }); + application.Bootstrap(bootstrapStopped, bootstrapNotStopped); + Assert.AreEqual(string.Empty, bootstrapStopped.value); + Assert.AreEqual("bootstrap", bootstrapNotStopped.value); + } + + public class StopProvider : IServiceProvider + { + public string value = string.Empty; + public bool stop = false; + public void Register() + { + value = "register"; + } + public void Init() + { + } + } + + [TestMethod] + public void TestStopRegisterProvider() + { + var providerStopped = new StopProvider() { stop = true }; + var providerNotStopped = new StopProvider(); + + var application = Application.New(); + application.Listen(ApplicationEvents.OnRegisterProvider, (b) => + { + if (((StopProvider)b).stop) + { + return false; + } + return null; + }); + application.Register(providerStopped); + application.Register(providerNotStopped); + Assert.AreEqual(string.Empty, providerStopped.value); + Assert.AreEqual("register", providerNotStopped.value); + } + + [TestMethod] + [ExpectedException(typeof(RuntimeException))] + public void TestInitingRegisterProvider() + { + var application = Application.New(); + application.Register(new StopProvider()); + application.On(ApplicationEvents.OnIniting, (b) => + { + application.Register(new TestServiceProvider()); + }); + application.Bootstrap(); + application.Init(); + } + + [TestMethod] + [ExpectedException(typeof(RuntimeException))] + public void TestTerminateRegisterProvider() + { + var application = Application.New(); + application.Register(new StopProvider()); + application.On(ApplicationEvents.OnTerminate, () => + { + application.Register(new TestServiceProvider()); + }); + application.Bootstrap(); + application.Init(); + application.Terminate(); + } + /// /// 测试终止程序 /// @@ -164,7 +257,7 @@ public void TestOn() public void GetCurrentProcess() { var app = MakeApplication(); - Assert.AreEqual(Application.StartProcess.Inited, app.Process); + Assert.AreEqual(Application.StartProcess.Running, app.Process); } [TestMethod] @@ -178,13 +271,13 @@ public void TestDebugLevel() /// 重复的引导测试 /// [TestMethod] + [ExpectedException(typeof(RuntimeException))] public void RepeatBootstrap() { var app = new Application(); app.Bootstrap(); app.Init(); app.Bootstrap(); - Assert.AreEqual(Application.StartProcess.Inited, app.Process); } /// diff --git a/src/CatLib.Core.Tests/Properties/AssemblyInfo.cs b/src/CatLib.Core.Tests/Properties/AssemblyInfo.cs index 0d84fab..e32692f 100644 --- a/src/CatLib.Core.Tests/Properties/AssemblyInfo.cs +++ b/src/CatLib.Core.Tests/Properties/AssemblyInfo.cs @@ -26,4 +26,4 @@ [assembly: Guid("3c9f4024-910c-4881-a04d-34a6c3a09019")] [assembly: AssemblyVersion("1.2.0.0")] -[assembly: AssemblyFileVersion("1.2.11.0")] +[assembly: AssemblyFileVersion("1.2.12.0")] diff --git a/src/CatLib.Core.Tests/Support/Util/DictTests.cs b/src/CatLib.Core.Tests/Support/Util/DictTests.cs index 845377c..06fcd64 100644 --- a/src/CatLib.Core.Tests/Support/Util/DictTests.cs +++ b/src/CatLib.Core.Tests/Support/Util/DictTests.cs @@ -77,6 +77,14 @@ public void TestSetRemove() Assert.AreEqual(false, Dict.Remove(dict, "hello.name.is.world")); } + [TestMethod] + public void TestSetNotObject() + { + var dict = new Dictionary(); + dict.Add("string", "string"); + Dict.Set(dict, "string.hello", "hello"); + } + [TestMethod] public void TestKeys() { diff --git a/src/CatLib.Core.Tests/Support/Util/StreamExtensionTests.cs b/src/CatLib.Core.Tests/Support/Util/StreamExtensionTests.cs index 5d2ad7e..b350248 100644 --- a/src/CatLib.Core.Tests/Support/Util/StreamExtensionTests.cs +++ b/src/CatLib.Core.Tests/Support/Util/StreamExtensionTests.cs @@ -59,6 +59,21 @@ public void TestStreamToTextLarage() Assert.AreEqual(builder.ToString(), stream1.ToText()); } + [TestMethod] + public void TestChineseText() + { + var stream1 = new StorageStream(new MemoryStorage()); + var builder = new StringBuilder(); + for (var i = 0; i < (ThreadStatic.Buffer.Length / 10) + 1; i++) + { + var data = Encoding.UTF8.GetBytes("12中文34测试的5这是67890"); + stream1.Write(data, 0, data.Length); + builder.Append("12中文34测试的5这是67890"); + } + stream1.Seek(0, SeekOrigin.Begin); + Assert.AreEqual(builder.ToString(), stream1.ToText()); + } + [TestMethod] public void TestStreamToTextEmpty() { diff --git a/src/CatLib.Core/CatLib.Core.csproj b/src/CatLib.Core/CatLib.Core.csproj index 8230290..3f2adb0 100644 --- a/src/CatLib.Core/CatLib.Core.csproj +++ b/src/CatLib.Core/CatLib.Core.csproj @@ -44,6 +44,10 @@ + + + + diff --git a/src/CatLib.Core/CatLib/App.cs b/src/CatLib.Core/CatLib/App.cs index b2a2ed0..65add84 100644 --- a/src/CatLib.Core/CatLib/App.cs +++ b/src/CatLib.Core/CatLib/App.cs @@ -41,7 +41,7 @@ public static IApplication Handler { if (instance == null) { - Application.New(); + return New(); } return instance; } @@ -54,6 +54,15 @@ public static IApplication Handler } } } + + /// + /// 创建CatLib实例 + /// + /// CatLib实例 + protected static IApplication New() + { + return Application.New(); + } #endregion #region Application API diff --git a/src/CatLib.Core/CatLib/Application.cs b/src/CatLib.Core/CatLib/Application.cs index 444d627..c4e14ea 100644 --- a/src/CatLib.Core/CatLib/Application.cs +++ b/src/CatLib.Core/CatLib/Application.cs @@ -23,7 +23,7 @@ public class Application : Container, IApplication, IOriginalDispatcher /// /// 版本号 /// - private readonly Version version = new Version("1.2.11"); + private readonly Version version = new Version("1.2.12"); /// /// 框架启动流程 @@ -36,34 +36,54 @@ public enum StartProcess Construct = 0, /// - /// 引导流程 + /// 引导流程之前 /// Bootstrap = 1, /// - /// 引导流程结束 + /// 引导流程进行中 /// - Bootstraped = 2, + Bootstrapping = 2, + + /// + /// 引导流程结束之后 + /// + Bootstraped = 3, + + /// + /// 初始化开始之前 + /// + Init = 4, /// /// 初始化中 /// - Initing = 3, + Initing = 5, /// - /// 初始化完成 + /// 初始化完成后 /// - Inited = 4, + Inited = 6, + + /// + /// 框架运行中 + /// + Running = 7, /// /// 框架终止之前 /// - Terminate = 5, + Terminate = 8, + + /// + /// 框架终止进行中 + /// + Terminating = 9, /// /// 框架终止之后 /// - Terminated = 6, + Terminated = 10, } /// @@ -89,7 +109,7 @@ public enum StartProcess /// /// 启动流程 /// - private StartProcess process = StartProcess.Construct; + private StartProcess process; /// /// 启动流程 @@ -150,7 +170,8 @@ public Application() RegisterCoreAlias(); RegisterCoreService(); OnFindType(finder => { return Type.GetType(finder); }); - DebugLevel = DebugLevels.Prod; + DebugLevel = DebugLevels.Production; + Process = StartProcess.Construct; } /// @@ -169,6 +190,7 @@ public virtual void Terminate() { Process = StartProcess.Terminate; Trigger(ApplicationEvents.OnTerminate, this); + Process = StartProcess.Terminating; Flush(); App.Handler = null; Process = StartProcess.Terminated; @@ -185,12 +207,14 @@ public virtual void Bootstrap(params IBootstrap[] bootstraps) { Guard.Requires(bootstraps != null); - if (bootstrapped) + if (bootstrapped || Process != StartProcess.Construct) { - return; + throw new RuntimeException("Cannot repeatedly trigger the Bootstrap()"); } Process = StartProcess.Bootstrap; + Trigger(ApplicationEvents.OnBootstrap, this); + Process = StartProcess.Bootstrapping; var sorting = new SortSet(); @@ -201,7 +225,8 @@ public virtual void Bootstrap(params IBootstrap[] bootstraps) foreach (var bootstrap in sorting) { - if (bootstrap != null) + var allow = TriggerHalt(ApplicationEvents.Bootstrapping, bootstrap) == null; + if (bootstrap != null && allow) { bootstrap.Bootstrap(); } @@ -223,11 +248,13 @@ public virtual void Init() throw new RuntimeException("You must call Bootstrap() first."); } - if (inited) + if (inited || Process != StartProcess.Bootstraped) { - return; + throw new RuntimeException("Cannot repeatedly trigger the Init()"); } + Process = StartProcess.Init; + Trigger(ApplicationEvents.OnInit, this); Process = StartProcess.Initing; foreach (var provider in serviceProviders) @@ -238,7 +265,9 @@ public virtual void Init() inited = true; Process = StartProcess.Inited; + Trigger(ApplicationEvents.OnInited, this); + Process = StartProcess.Running; Trigger(ApplicationEvents.OnStartCompleted, this); } @@ -256,6 +285,22 @@ public virtual void Register(IServiceProvider provider) throw new RuntimeException("Provider [" + provider.GetType() + "] is already register."); } + if(Process == StartProcess.Initing) + { + throw new RuntimeException("Unable to add service provider during StartProcess.Initing"); + } + + if(Process > StartProcess.Running) + { + throw new RuntimeException("Unable to Terminate in-process registration service provider"); + } + + var allow = TriggerHalt(ApplicationEvents.OnRegisterProvider, provider) == null; + if (!allow) + { + return; + } + provider.Register(); serviceProviders.Add(provider, GetPriority(provider.GetType(), "Init")); serviceProviderTypes.Add(GetProviderBaseType(provider)); diff --git a/src/CatLib.Core/CatLib/ApplicationEvents.cs b/src/CatLib.Core/CatLib/ApplicationEvents.cs index 12d9145..69fd2da 100644 --- a/src/CatLib.Core/CatLib/ApplicationEvents.cs +++ b/src/CatLib.Core/CatLib/ApplicationEvents.cs @@ -16,16 +16,41 @@ namespace CatLib /// public sealed class ApplicationEvents { + /// + /// 当引导程序开始之前 + /// + public static readonly string OnBootstrap = "CatLib.ApplicationEvents.OnBootstrap"; + + /// + /// 当引导程序进行中 + /// + public static readonly string Bootstrapping = "CatLib.ApplicationEvents.Bootstrapping"; + /// /// 当引导完成时 /// public static readonly string OnBootstraped = "CatLib.ApplicationEvents.OnBootstraped"; + /// + /// 当注册服务提供者 + /// + public static readonly string OnRegisterProvider = "CatLib.ApplicationEvents.OnRegisterProvider"; + + /// + /// 当初始化开始之前 + /// + public static readonly string OnInit = "CatLib.ApplicationEvents.OnInit"; + /// /// 当初始化进行时 /// public static readonly string OnIniting = "CatLib.ApplicationEvents.OnIniting"; + /// + /// 当初始化完成之后 + /// + public static readonly string OnInited = "CatLib.ApplicationEvents.OnInited"; + /// /// 当程序启动完成 /// diff --git a/src/CatLib.Core/CatLib/DebugLevels.cs b/src/CatLib.Core/CatLib/DebugLevels.cs index 06ab8d1..11a00bb 100644 --- a/src/CatLib.Core/CatLib/DebugLevels.cs +++ b/src/CatLib.Core/CatLib/DebugLevels.cs @@ -9,6 +9,8 @@ * Document: http://catlib.io/ */ +using System; + namespace CatLib { /// @@ -19,8 +21,14 @@ public enum DebugLevels /// /// 生产环境 /// + [Obsolete("Please use Production")] Prod, + /// + /// 生产环境 + /// + Production, + /// /// 仿真环境 /// @@ -29,6 +37,12 @@ public enum DebugLevels /// /// 开发者模式 /// + [Obsolete("Please use Development")] Dev, + + /// + /// 开发者模式 + /// + Development, } } \ No newline at end of file diff --git a/src/CatLib.Core/CatLib/Facades/Template/Managed.cs b/src/CatLib.Core/CatLib/Facades/Template/Managed.cs new file mode 100644 index 0000000..b0fcd4a --- /dev/null +++ b/src/CatLib.Core/CatLib/Facades/Template/Managed.cs @@ -0,0 +1,66 @@ +/* + * Code Generation File 2018/10/16 + */ + +/* + * This file is part of the CatLib package. + * + * (c) Yu Bin + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * Document: http://catlib.io/ + */ + +using System; + +namespace CatLib.Facades.Template +{ + /// + /// 管理器模版 + /// + /// 主服务接口 + /// 扩展类型接口 + [ExcludeFromCodeCoverage] + public abstract class Managed : Facade + where TInterface : IManaged + { + /// + /// 当扩展被实现时 + /// + public static event Action OnResolving + { + add { Instance.OnResolving += value; } + remove { Instance.OnResolving -= value; } + } + + /// + /// 自定义一个扩展构建器 + /// + /// 扩展构建器 + /// 扩展名 + public static void Extend(Func builder, string name = null) + { + Instance.Extend(builder, name); + } + + /// + /// 释放指定扩展的构建器 + /// + /// 扩展名 + public static void RemoveExtend(string name = null) + { + Instance.RemoveExtend(name); + } + + /// + /// 是否包含指定扩展构建器 + /// + /// 扩展名 + public static bool ContainsExtend(string name = null) + { + return Instance.ContainsExtend(name); + } + } +} diff --git a/src/CatLib.Core/CatLib/Facades/Template/Manager.cs b/src/CatLib.Core/CatLib/Facades/Template/Manager.cs new file mode 100644 index 0000000..d9c4d45 --- /dev/null +++ b/src/CatLib.Core/CatLib/Facades/Template/Manager.cs @@ -0,0 +1,37 @@ +/* + * Code Generation File 2018/10/16 + */ + +/* + * This file is part of the CatLib package. + * + * (c) Yu Bin + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * Document: http://catlib.io/ + */ + +namespace CatLib.Facades.Template +{ + /// + /// 管理器模版 + /// + /// 主服务接口 + /// 扩展类型接口 + [ExcludeFromCodeCoverage] + public abstract class Manager : Managed + where TInterface : IManager + { + /// + /// 获取扩展实现 + /// + /// 扩展名 + /// 扩展实现 + public static TExtend Get(string name = null) + { + return Instance.Get(name); + } + } +} diff --git a/src/CatLib.Core/CatLib/Facades/Template/SingleManaged.cs b/src/CatLib.Core/CatLib/Facades/Template/SingleManaged.cs new file mode 100644 index 0000000..d9f0286 --- /dev/null +++ b/src/CatLib.Core/CatLib/Facades/Template/SingleManaged.cs @@ -0,0 +1,57 @@ +/* + * Code Generation File 2018/10/16 + */ + +/* + * This file is part of the CatLib package. + * + * (c) Yu Bin + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * Document: http://catlib.io/ + */ + +using System; + +namespace CatLib.Facades.Template +{ + /// + /// 管理器模版 + /// + /// 主服务接口 + /// 扩展类型接口 + [ExcludeFromCodeCoverage] + public abstract class SingleManaged : Managed + where TInterface : ISingleManaged + { + /// + /// 当释放时 + /// + public static event Action OnRelease + { + add { Instance.OnRelease += value; } + remove { Instance.OnRelease -= value; } + } + + /// + /// 释放指定的扩展实现 + /// + /// 扩展名 + public static void Release(string name = null) + { + Instance.Release(name); + } + + /// + /// 是否包含指定的扩展实现 + /// + /// 扩展名 + /// 是否包含扩展实现 + public static bool Contains(string name = null) + { + return Instance.Contains(name); + } + } +} diff --git a/src/CatLib.Core/CatLib/Facades/Template/SingleManager.cs b/src/CatLib.Core/CatLib/Facades/Template/SingleManager.cs new file mode 100644 index 0000000..5b1ce73 --- /dev/null +++ b/src/CatLib.Core/CatLib/Facades/Template/SingleManager.cs @@ -0,0 +1,45 @@ +/* + * Code Generation File 2018/10/16 + */ + +/* + * This file is part of the CatLib package. + * + * (c) Yu Bin + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * Document: http://catlib.io/ + */ + +namespace CatLib.Facades.Template +{ + /// + /// 管理器模版 + /// + /// 主服务接口 + /// 扩展类型接口 + [ExcludeFromCodeCoverage] + public abstract class SingleManager : SingleManaged + where TInterface : ISingleManager + { + /// + /// 获取扩展实现 + /// + /// 扩展名 + /// 扩展实现 + public static TExtend Get(string name = null) + { + return Instance.Get(name); + } + + /// + /// 默认的扩展实现 + /// + public static TExtend Default + { + get { return Instance.Default; } + } + } +} diff --git a/src/CatLib.Core/Properties/AssemblyInfo.cs b/src/CatLib.Core/Properties/AssemblyInfo.cs index bedfc46..a563c3d 100644 --- a/src/CatLib.Core/Properties/AssemblyInfo.cs +++ b/src/CatLib.Core/Properties/AssemblyInfo.cs @@ -27,7 +27,7 @@ [assembly: Guid("4204658e-81fd-4106-a347-890cd369c8a4")] [assembly: AssemblyVersion("1.2.0.0")] -[assembly: AssemblyFileVersion("1.2.11.0")] +[assembly: AssemblyFileVersion("1.2.12.0")] [assembly: InternalsVisibleTo("Assembly-CSharp-Editor"), InternalsVisibleTo("Assembly-CSharp-Editor-firstpass"), diff --git a/src/CatLib.Core/Support/Util/Arr.cs b/src/CatLib.Core/Support/Util/Arr.cs index 8e2e189..ee7df94 100644 --- a/src/CatLib.Core/Support/Util/Arr.cs +++ b/src/CatLib.Core/Support/Util/Arr.cs @@ -10,7 +10,6 @@ */ using System; -using System.Collections.Generic; namespace CatLib { diff --git a/src/CatLib.Core/Support/Util/Dict.cs b/src/CatLib.Core/Support/Util/Dict.cs index b08745b..dd8ee47 100644 --- a/src/CatLib.Core/Support/Util/Dict.cs +++ b/src/CatLib.Core/Support/Util/Dict.cs @@ -53,7 +53,8 @@ public static IDictionary Filter(IDictionary规定字典 /// 回调函数 /// 被移除的元素 - public static KeyValuePair[] Remove(IDictionary source, Func predicate) + public static KeyValuePair[] Remove(IDictionary source + , Func predicate) { Guard.Requires(source != null); Guard.Requires(predicate != null); @@ -82,7 +83,8 @@ public static KeyValuePair[] Remove(IDictionary字典值类型 /// 规定字典 /// 回调函数 - public static void Modify(IDictionary source, Func callback) + public static void Modify(IDictionary source + , Func callback) { Guard.Requires(source != null); Guard.Requires(callback != null); @@ -91,13 +93,18 @@ public static void Modify(IDictionary source, Func(); elements[result.Key] = value; } } + if(elements == null) + { + return; + } + foreach (var result in elements) { source[result.Key] = result.Value; @@ -112,7 +119,8 @@ public static void Modify(IDictionary source, Func目标字典 /// 增加的内容 /// 遇到重复是否替换,如果不进行替换遇到重复将会抛出一个异常 - public static void AddRange(IDictionary source, IDictionary added, bool replaced = true) + public static void AddRange(IDictionary source + , IDictionary added, bool replaced = true) { Guard.Requires(source != null); if (added == null) @@ -141,7 +149,8 @@ public static void AddRange(IDictionary source, IDic /// 规定字典 /// 自定义函数 /// 处理后的字典 - public static IDictionary Map(IDictionary source, Func callback) + public static IDictionary Map(IDictionary source + , Func callback) { Guard.Requires(source != null); Guard.Requires(callback != null); diff --git a/src/CatLib.Core/Support/Util/Extension/StreamExtension.cs b/src/CatLib.Core/Support/Util/Extension/StreamExtension.cs index a011416..5d0fb40 100644 --- a/src/CatLib.Core/Support/Util/Extension/StreamExtension.cs +++ b/src/CatLib.Core/Support/Util/Extension/StreamExtension.cs @@ -85,7 +85,7 @@ public static string ToText(this Stream source, Encoding encoding = null, bool c var length = 0; try { - length = (int) source.Length; + length = (int)source.Length; } catch (NotSupportedException) { @@ -105,7 +105,7 @@ public static string ToText(this Stream source, Encoding encoding = null, bool c using (targetStream) { var read = source.AppendTo(targetStream); - return encoding.GetString(targetStream.GetBuffer(), 0, (int) read); + return encoding.GetString(targetStream.GetBuffer(), 0, (int)read); } } finally