diff --git a/src/CatLib.Core.Tests/CatLib/ApplicationTests.cs b/src/CatLib.Core.Tests/CatLib/ApplicationTests.cs
index 6b6c39c..f619a09 100644
--- a/src/CatLib.Core.Tests/CatLib/ApplicationTests.cs
+++ b/src/CatLib.Core.Tests/CatLib/ApplicationTests.cs
@@ -481,6 +481,111 @@ public void TestRegisterProcessMake()
app.Register(new TestRegisterProcessMakeServiceProvider());
}
+ public class TestExistedBoostrap : IBootstrap
+ {
+ public void Bootstrap()
+ {
+
+ }
+ }
+
+ [TestMethod]
+ [ExpectedException(typeof(LogicException))]
+ public void TestExistBoostrap()
+ {
+ var app = new Application();
+ var boostrap = new TestExistedBoostrap();
+ app.Bootstrap(boostrap, boostrap);
+ }
+
+ private static int assertValue = 0;
+
+ public class OrderAssertClass : IBootstrap, IServiceProvider
+ {
+ private readonly int assert;
+ public OrderAssertClass(int assert)
+ {
+ this.assert = assert;
+ }
+
+ public void Bootstrap()
+ {
+ Assert.AreEqual(assert, assertValue++);
+ }
+
+ ///
+ /// 服务提供者初始化
+ ///
+ public void Init()
+ {
+ Bootstrap();
+ }
+
+ ///
+ /// 当注册服务提供者
+ ///
+ public void Register()
+ {
+
+ }
+ }
+
+ public class OrderAssertClassSub : OrderAssertClass
+ {
+ public OrderAssertClassSub(int assert)
+ :base(assert)
+ {
+
+ }
+ }
+
+ [Priority(0)]
+ public class OrderFirstClass : IBootstrap, IServiceProvider
+ {
+ public void Bootstrap()
+ {
+ Assert.AreEqual(0, assertValue);
+ }
+
+ ///
+ /// 服务提供者初始化
+ ///
+ public void Init()
+ {
+ Bootstrap();
+ }
+
+ ///
+ /// 当注册服务提供者
+ ///
+ public void Register()
+ {
+
+ }
+ }
+
+ [TestMethod]
+ public void TestBoostrapOrder()
+ {
+ assertValue = 0;
+ var app = new Application();
+ app.Bootstrap(new OrderAssertClass(0), new OrderFirstClass(), new OrderAssertClass(1));
+ Assert.AreEqual(2, assertValue);
+ }
+
+ [TestMethod]
+ public void TestProviderOrder()
+ {
+ assertValue = 0;
+ var app = new Application();
+ app.Bootstrap();
+ app.Register(new OrderAssertClass(0));
+ app.Register(new OrderFirstClass());
+ app.Register(new OrderAssertClassSub(1));
+ app.Init();
+ Assert.AreEqual(2, assertValue);
+ }
+
private Application MakeApplication()
{
var app = new Application();
diff --git a/src/CatLib.Core.Tests/Support/Container/GivenDataTests.cs b/src/CatLib.Core.Tests/Support/Container/GivenDataTests.cs
index c279dea..822075e 100644
--- a/src/CatLib.Core.Tests/Support/Container/GivenDataTests.cs
+++ b/src/CatLib.Core.Tests/Support/Container/GivenDataTests.cs
@@ -52,12 +52,120 @@ public void CheckGivenIllegalValue()
ExceptionAssert.Throws(() =>
{
- givenData.Given(null);
+ givenData.Given(string.Empty);
});
- ExceptionAssert.Throws(() =>
+ }
+
+
+ private class TestGivenClosureClass
+ {
+ public string Name { get; set; }
+ public int Value { get; set; }
+ public TestGivenClosureClass(string name, int value = 0)
{
- givenData.Given(string.Empty);
+ Name = name;
+ Value = value;
+ }
+ }
+
+ [TestMethod]
+ public void TestGivenClosure()
+ {
+ var container = new Container();
+ container.Bind().Needs().Given(() => "hello world")
+ .Needs().Given(()=> 10);
+
+ Assert.AreEqual("hello world", container.Make().Name);
+ Assert.AreEqual(10, container.Make().Value);
+ }
+
+ [TestMethod]
+ [ExpectedException(typeof(LogicException))]
+ public void TestGivenDuplicateValue()
+ {
+ var container = new Container();
+ container.Bind().Needs().Given(() => "hello world");
+ container.Bind().Needs().Given(() => "ddd");
+ }
+
+ [TestMethod]
+ [ExpectedException(typeof(LogicException))]
+ public void TestGivenDuplicateValue2()
+ {
+ var container = new Container();
+ container.Bind().Needs().Given(() => "hello world");
+ container.Bind().Needs().Given();
+ }
+
+ [TestMethod]
+ [ExpectedException(typeof(LogicException))]
+ public void TestGivenDuplicateValue3()
+ {
+ var container = new Container();
+ container.Bind().Needs().Given();
+ container.Bind().Needs().Given(() => "hello world");
+ }
+
+ [TestMethod]
+ [ExpectedException(typeof(LogicException))]
+ public void TestGivenDuplicateValue4()
+ {
+ var container = new Container();
+ container.Bind().Needs().Given();
+ container.Bind().Needs().Given();
+ }
+
+ [TestMethod]
+ [ExpectedException(typeof(LogicException))]
+ public void TestGivenDuplicateValue5()
+ {
+ var container = new Container();
+ container.Bind().Needs().Given(() => "hello world");
+ container.Bind().Needs().Given();
+ container.Bind().Needs().Given();
+ }
+
+ [TestMethod]
+ [ExpectedException(typeof(LogicException))]
+ public void TestGivenDuplicateValue6()
+ {
+ var container = new Container();
+ container.Bind().Needs().Given();
+ container.Bind().Needs().Given(() => "hello world");
+ container.Bind().Needs().Given(() => "hello world");
+ }
+
+ [TestMethod]
+ [ExpectedException(typeof(AssertException))]
+ public void TestGivenClosureException()
+ {
+ var container = new Container();
+ container.Bind().Needs().Given(() =>
+ {
+ throw new AssertException("hello world");
});
+
+ container.Make();
+ }
+
+ private class TestGivenClosureAttrClass
+ {
+ [Inject]
+ public string Name { get; set; }
+
+ [Inject]
+ public int Value { get; set; }
+ }
+
+ [TestMethod]
+ public void TestGivenAttrClosure()
+ {
+ var container = new Container();
+ container.Bind().Needs().Given(() => "hello world")
+ .Needs().Given(() => 10);
+
+ Assert.AreEqual("hello world", container.Make().Name);
+ Assert.AreEqual(10, container.Make().Value);
}
}
}
\ No newline at end of file
diff --git a/src/CatLib.Core/CatLib/Application.cs b/src/CatLib.Core/CatLib/Application.cs
index 5f0e483..419be23 100644
--- a/src/CatLib.Core/CatLib/Application.cs
+++ b/src/CatLib.Core/CatLib/Application.cs
@@ -90,7 +90,8 @@ public enum StartProcess
///
/// 服务提供者
///
- private readonly SortSet serviceProviders = new SortSet();
+ private readonly List> serviceProviders =
+ new List>();
///
/// 注册服务提供者
@@ -198,18 +199,31 @@ public virtual void Bootstrap(params IBootstrap[] bootstraps)
Trigger(ApplicationEvents.OnBootstrap, this);
Process = StartProcess.Bootstrapping;
- var sorting = new SortSet();
+ var sorting = new List>();
+ var existed = new HashSet();
foreach (var bootstrap in bootstraps)
{
- if (bootstrap != null)
+ if (bootstrap == null)
{
- sorting.Add(bootstrap, GetPriority(bootstrap.GetType(), nameof(IBootstrap.Bootstrap)));
+ continue;
}
+
+ if (existed.Contains(bootstrap))
+ {
+ throw new LogicException($"The bootstrap already exists : {bootstrap}");
+ }
+
+ existed.Add(bootstrap);
+ sorting.Add(new KeyValuePair(bootstrap,
+ GetPriority(bootstrap.GetType(), nameof(IBootstrap.Bootstrap))));
}
- foreach (var bootstrap in sorting)
+ sorting.Sort((left, right) => left.Value.CompareTo(right.Value));
+
+ foreach (var kv in sorting)
{
+ var bootstrap = kv.Key;
var allow = TriggerHalt(ApplicationEvents.Bootstrapping, bootstrap) == null;
if (bootstrap != null && allow)
{
@@ -250,9 +264,11 @@ protected IEnumerator CoroutineInit()
Trigger(ApplicationEvents.OnInit, this);
Process = StartProcess.Initing;
+ serviceProviders.Sort((left, right) => left.Value.CompareTo(right.Value));
+
foreach (var provider in serviceProviders)
{
- yield return InitProvider(provider);
+ yield return InitProvider(provider.Key);
}
inited = true;
@@ -312,7 +328,10 @@ protected IEnumerator CoroutineRegister(IServiceProvider provider)
{
registering = false;
}
- serviceProviders.Add(provider, GetPriority(provider.GetType(), nameof(IServiceProvider.Init)));
+
+ serviceProviders.Add(
+ new KeyValuePair(provider,
+ GetPriority(provider.GetType(), nameof(IServiceProvider.Init))));
serviceProviderTypes.Add(GetProviderBaseType(provider));
if (inited)
diff --git a/src/CatLib.Core/Support/Container/Bindable.cs b/src/CatLib.Core/Support/Container/Bindable.cs
index b32372c..33b7ab8 100644
--- a/src/CatLib.Core/Support/Container/Bindable.cs
+++ b/src/CatLib.Core/Support/Container/Bindable.cs
@@ -9,6 +9,7 @@
* Document: http://catlib.io/
*/
+using System;
using System.Collections.Generic;
namespace CatLib
@@ -34,6 +35,12 @@ public abstract class Bindable : IBindable
///
private Dictionary contextual;
+ ///
+ /// 服务上下文闭包
+ /// 当前服务需求某个服务时给定的闭包
+ ///
+ private Dictionary> contextualClosure;
+
///
/// 同步锁
///
@@ -83,7 +90,8 @@ internal void AddContextual(string needs, string given)
{
contextual = new Dictionary();
}
- if (contextual.ContainsKey(needs))
+ if (contextual.ContainsKey(needs)
+ || (contextualClosure != null && contextualClosure.ContainsKey(needs)))
{
throw new LogicException($"Needs [{needs}] is already exist.");
}
@@ -91,6 +99,29 @@ internal void AddContextual(string needs, string given)
}
}
+ ///
+ /// 为服务增加上下文
+ ///
+ /// 需求什么服务
+ /// 给与什么服务
+ internal void AddContextual(string needs, Func