Skip to content

Commit cbc30c2

Browse files
committed
resolved #122
1 parent 276a3d4 commit cbc30c2

File tree

4 files changed

+96
-134
lines changed

4 files changed

+96
-134
lines changed

src/CatLib.Core.Tests/Support/Container/BindDataTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ public void CanGetContextual()
7171

7272
Assert.AreEqual("abc", bindData.GetContextual("need1"));
7373
Assert.AreEqual(container.Type2Service(typeof(BindDataTest)), bindData.GetContextual("need2"));
74-
Assert.AreEqual("empty", bindData.GetContextual("empty"));
74+
Assert.AreEqual(null, bindData.GetContextual("empty"));
7575
}
7676
#endregion
7777

src/CatLib.Core.Tests/Support/Container/ContainerTests.cs

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -700,12 +700,15 @@ public void CheckIllegalCallMethod()
700700
public void TestContainerCallWithNullParams()
701701
{
702702
var container = MakeContainer();
703-
container.Instance("num", 777);
704-
container.Alias("$num", "num");
705-
var result = container.Call(this, "TestContainerCall", null);
703+
var result = container.Call(this, "TestContainerCallEmpty", null);
706704
Assert.AreEqual(777, result);
707705
}
708706

707+
public int TestContainerCallEmpty()
708+
{
709+
return 777;
710+
}
711+
709712
[TestMethod]
710713
public void TestContainerCallWithErrorParams()
711714
{
@@ -849,7 +852,7 @@ public class NoClassAttrInject
849852
public void MakeNoClassAttrInject()
850853
{
851854
var container = MakeContainer();
852-
container.Bind<NoClassAttrInject>();
855+
container.Bind<NoClassAttrInject>().Needs("$Time").Given("Time");
853856
container.Bind("Time", (c, p) => 100, false).Alias("$Time");
854857

855858
var result = container.Make<NoClassAttrInject>();
@@ -905,9 +908,9 @@ public void MakeNoParamConstructor()
905908
public void MakeNotClassConstructor()
906909
{
907910
var container = MakeContainer();
908-
container.Bind<MakeTestNoParamClass>();
911+
container.Bind<MakeTestNoParamClass>().Needs("$i").Given("i");
909912
container.Bind<MakeTestClassDependency>();
910-
container.Singleton("i", (_,__) => 77).Alias("$i");
913+
container.Singleton("i", (_,__) => 77);
911914
var result = container.Make<MakeTestNoParamClass>();
912915
Assert.AreEqual(77, result.I);
913916
Assert.AreNotEqual(null, result.Dependency);
@@ -1187,8 +1190,7 @@ public TestInjectNullClass(TestMakeBasePrimitiveConstructor cls)
11871190
public void TestInjectNull()
11881191
{
11891192
var container = new SupportNullContainer() as IContainer;
1190-
container.Bind<TestInjectNullClass>();
1191-
1193+
container.Bind<TestInjectNullClass>().Needs("$cls").Given(() => null);
11921194
container.Make<TestInjectNullClass>();
11931195
}
11941196

@@ -1847,9 +1849,7 @@ public void TestBaseStructChangeInvalid()
18471849
public void TestFormatException()
18481850
{
18491851
var container = new Container();
1850-
container.Instance("num", 10);
1851-
container.Alias("$num", "num");
1852-
Assert.AreEqual(10, container.Call(this, "TestContainerCall", new ContainerTest()));
1852+
Assert.AreEqual(10, container.Call(this, "TestContainerCall", new ContainerTest(),10));
18531853
}
18541854

18551855
internal class TestNoConstructorAccessClass
@@ -2020,14 +2020,14 @@ public TestResloveAttrClassSpeculationService(UnresolvableException ex)
20202020
public void TestResloveAttrClassSpeculationServiceFunc()
20212021
{
20222022
var container = new Container();
2023-
container.Bind<TestResloveAttrClassSpeculationService>();
2023+
container.Bind<TestResloveAttrClassSpeculationService>()
2024+
.Needs("$ex").Given("ex")
2025+
.Needs("$rex").Given("rex");
20242026
container.Instance("ex", new UnresolvableException());
2025-
container.Alias("$ex", "ex");
20262027
container.Instance("rex", new UnresolvableException());
2027-
container.Alias("$rex", "rex");
20282028
var cls = container.Make<TestResloveAttrClassSpeculationService>();
20292029

2030-
Assert.AreSame(container.Make("$ex"), cls.ex);
2030+
Assert.AreSame(container.Make("ex"), cls.ex);
20312031
}
20322032

20332033
[TestMethod]

src/CatLib.Core/Support/Container/Bindable.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,9 +131,9 @@ internal string GetContextual(string needs)
131131
{
132132
if (contextual == null)
133133
{
134-
return needs;
134+
return null;
135135
}
136-
return contextual.TryGetValue(needs, out string contextualNeeds) ? contextualNeeds : needs;
136+
return contextual.TryGetValue(needs, out string contextualNeeds) ? contextualNeeds : null;
137137
}
138138

139139
/// <summary>

src/CatLib.Core/Support/Container/Container.cs

Lines changed: 78 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -1154,61 +1154,100 @@ protected virtual string GetParamNeedsService(ParameterInfo baseParam)
11541154
/// 根据上下文获取相关的构建闭包
11551155
/// </summary>
11561156
/// <param name="makeServiceBindData">请求注入操作的服务绑定数据</param>
1157-
/// <param name="service">服务名</param>
1157+
/// <param name="service">构建的服务名</param>
11581158
/// <param name="paramName">目标参数的名字</param>
11591159
/// <returns>构建闭包</returns>
11601160
protected virtual Func<object> GetContextualClosure(Bindable makeServiceBindData, string service,
11611161
string paramName)
11621162
{
11631163
return makeServiceBindData.GetContextualClosure(service) ??
1164-
makeServiceBindData.GetContextualClosure($"${paramName}");
1164+
makeServiceBindData.GetContextualClosure($"{GetVariableTag()}{paramName}");
1165+
}
1166+
1167+
/// <summary>
1168+
/// 根据上下文获取相关的需求服务
1169+
/// </summary>
1170+
/// <param name="makeServiceBindData">请求注入操作的服务绑定数据</param>
1171+
/// <param name="service">构建的服务名</param>
1172+
/// <param name="paramName">目标参数的名字</param>
1173+
/// <returns>需求的服务名</returns>
1174+
protected virtual string GetContextual(Bindable makeServiceBindData, string service, string paramName)
1175+
{
1176+
return makeServiceBindData.GetContextual(service) ??
1177+
makeServiceBindData.GetContextual($"{GetVariableTag()}{paramName}") ??
1178+
service;
11651179
}
11661180

11671181
/// <summary>
11681182
/// 从上下文闭包中进行构建获得实例
11691183
/// </summary>
11701184
/// <param name="closure">上下文闭包</param>
11711185
/// <param name="needType">参数需求的类型</param>
1172-
/// <returns>构建的实例</returns>
1173-
protected virtual object MakeFromContextualClosure(Func<object> closure, Type needType)
1186+
/// <param name="ouput">构建的实例</param>
1187+
/// <returns>是否成功构建</returns>
1188+
protected virtual bool MakeFromContextualClosure(Func<object> closure, Type needType, out object ouput)
11741189
{
1175-
var instance = closure();
1176-
if (ChangeType(ref instance, needType))
1190+
ouput = null;
1191+
if (closure == null)
11771192
{
1178-
return instance;
1193+
return false;
11791194
}
11801195

1181-
throw new LogicException("Parameter type cannot be converted to : " + needType);
1196+
ouput = closure();
1197+
return ChangeType(ref ouput, needType);
11821198
}
11831199

11841200
/// <summary>
1185-
/// 解决基本类型
1201+
/// 从上下文关系的服务名获取服务实现
11861202
/// </summary>
1187-
/// <param name="makeServiceBindData">请求注入操作的服务绑定数据</param>
1188-
/// <param name="service">希望解决的服务名或者别名</param>
1189-
/// <param name="baseParam">当前正在解决的变量</param>
1190-
/// <returns>解决结果</returns>
1191-
protected virtual object ResolveAttrPrimitive(Bindable makeServiceBindData, string service, PropertyInfo baseParam)
1203+
/// <param name="service">上下文关系的服务名</param>
1204+
/// <param name="needType">参数需求类型</param>
1205+
/// <param name="output">构建的实例</param>
1206+
/// <returns>是否成功构建</returns>
1207+
protected virtual bool MakeFromContextualService(string service, Type needType, out object output)
11921208
{
1193-
var contextualClosure = GetContextualClosure(makeServiceBindData, service, baseParam.Name);
1194-
if (contextualClosure != null)
1209+
output = null;
1210+
if (!CanMake(service))
11951211
{
1196-
return MakeFromContextualClosure(contextualClosure, baseParam.PropertyType);
1212+
return false;
11971213
}
11981214

1199-
service = makeServiceBindData.GetContextual(service);
1200-
if (CanMake(service))
1201-
{
1202-
return Make(service);
1203-
}
1215+
output = Make(service);
1216+
return ChangeType(ref output, needType);
1217+
}
12041218

1205-
var result = SpeculationServiceByParamName(makeServiceBindData, baseParam.Name, baseParam.PropertyType);
1206-
if (result != null)
1219+
/// <summary>
1220+
/// 根据上下文来解决指定需求的服务
1221+
/// </summary>
1222+
/// <param name="makeServiceBindData">请求注入操作的服务绑定数据</param>
1223+
/// <param name="service">构建的服务名字</param>
1224+
/// <param name="paramName">目标参数的名字</param>
1225+
/// <param name="paramType">目标参数的类型</param>
1226+
/// <param name="output">构建的实例</param>
1227+
/// <returns>是否成功通过上下文解决</returns>
1228+
protected virtual bool ResloveFromContextual(Bindable makeServiceBindData, string service, string paramName,
1229+
Type paramType, out object output)
1230+
{
1231+
if (MakeFromContextualClosure(GetContextualClosure(makeServiceBindData, service, paramName),
1232+
paramType, out output))
12071233
{
1208-
return result;
1234+
return true;
12091235
}
12101236

1211-
throw MakeUnresolvablePrimitiveException(baseParam.Name, baseParam.DeclaringType);
1237+
return MakeFromContextualService(GetContextual(makeServiceBindData, service, paramName),
1238+
paramType, out output);
1239+
}
1240+
1241+
/// <summary>
1242+
/// 解决基本类型
1243+
/// </summary>
1244+
/// <param name="makeServiceBindData">请求注入操作的服务绑定数据</param>
1245+
/// <param name="service">希望解决的服务名或者别名</param>
1246+
/// <param name="baseParam">当前正在解决的变量</param>
1247+
/// <returns>解决结果</returns>
1248+
protected virtual object ResolveAttrPrimitive(Bindable makeServiceBindData, string service, PropertyInfo baseParam)
1249+
{
1250+
return ResloveAttrClass(makeServiceBindData, service, baseParam);
12121251
}
12131252

12141253
/// <summary>
@@ -1220,26 +1259,13 @@ protected virtual object ResolveAttrPrimitive(Bindable makeServiceBindData, stri
12201259
/// <returns>解决结果</returns>
12211260
protected virtual object ResloveAttrClass(Bindable makeServiceBindData, string service, PropertyInfo baseParam)
12221261
{
1223-
var contextualClosure = GetContextualClosure(makeServiceBindData, service, baseParam.Name);
1224-
if (contextualClosure != null)
1262+
if (ResloveFromContextual(makeServiceBindData, service, baseParam.Name, baseParam.PropertyType,
1263+
out object instance))
12251264
{
1226-
return MakeFromContextualClosure(contextualClosure, baseParam.PropertyType);
1265+
return instance;
12271266
}
12281267

1229-
try
1230-
{
1231-
// 我们不进行CanMake检查以避免一次hash
1232-
return Make(makeServiceBindData.GetContextual(service));
1233-
}
1234-
catch (Exception)
1235-
{
1236-
var result = SpeculationServiceByParamName(makeServiceBindData, baseParam.Name, baseParam.PropertyType);
1237-
if (result != null)
1238-
{
1239-
return result;
1240-
}
1241-
throw;
1242-
}
1268+
throw MakeUnresolvablePrimitiveException(baseParam.Name, baseParam.DeclaringType);
12431269
}
12441270

12451271
/// <summary>
@@ -1251,30 +1277,7 @@ protected virtual object ResloveAttrClass(Bindable makeServiceBindData, string s
12511277
/// <returns>解决结果</returns>
12521278
protected virtual object ResolvePrimitive(Bindable makeServiceBindData, string service, ParameterInfo baseParam)
12531279
{
1254-
var contextualClosure = GetContextualClosure(makeServiceBindData, service, baseParam.Name);
1255-
if (contextualClosure != null)
1256-
{
1257-
return MakeFromContextualClosure(contextualClosure, baseParam.ParameterType);
1258-
}
1259-
1260-
service = makeServiceBindData.GetContextual(service);
1261-
if (CanMake(service))
1262-
{
1263-
return Make(service);
1264-
}
1265-
1266-
var result = SpeculationServiceByParamName(makeServiceBindData, baseParam.Name, baseParam.ParameterType);
1267-
if (result != null)
1268-
{
1269-
return result;
1270-
}
1271-
1272-
if (baseParam.IsOptional)
1273-
{
1274-
return baseParam.DefaultValue;
1275-
}
1276-
1277-
throw MakeUnresolvablePrimitiveException(baseParam.Name, baseParam.Member.DeclaringType);
1280+
return ResloveClass(makeServiceBindData, service, baseParam);
12781281
}
12791282

12801283
/// <summary>
@@ -1286,68 +1289,27 @@ protected virtual object ResolvePrimitive(Bindable makeServiceBindData, string s
12861289
/// <returns>解决结果</returns>
12871290
protected virtual object ResloveClass(Bindable makeServiceBindData, string service, ParameterInfo baseParam)
12881291
{
1289-
var contextualClosure = GetContextualClosure(makeServiceBindData, service, baseParam.Name);
1290-
if (contextualClosure != null)
1291-
{
1292-
return MakeFromContextualClosure(contextualClosure, baseParam.ParameterType);
1293-
}
1294-
1295-
try
1296-
{
1297-
return Make(makeServiceBindData.GetContextual(service));
1298-
}
1299-
catch (UnresolvableException)
1292+
if (ResloveFromContextual(makeServiceBindData, service, baseParam.Name, baseParam.ParameterType,
1293+
out object instance))
13001294
{
1301-
var result = SpeculationServiceByParamName(makeServiceBindData, baseParam.Name, baseParam.ParameterType);
1302-
if (result != null)
1303-
{
1304-
return result;
1305-
}
1306-
1307-
if (baseParam.IsOptional)
1308-
{
1309-
return baseParam.DefaultValue;
1310-
}
1311-
1312-
throw;
1295+
return instance;
13131296
}
1314-
}
13151297

1316-
/// <summary>
1317-
/// 根据参数名字来推测服务
1318-
/// </summary>
1319-
/// <param name="makeServiceBindData">请求注入操作的服务绑定数据</param>
1320-
/// <param name="paramName">参数名</param>
1321-
/// <param name="paramType">参数类型</param>
1322-
/// <returns>推测的服务</returns>
1323-
protected virtual object SpeculationServiceByParamName(Bindable makeServiceBindData, string paramName, Type paramType)
1324-
{
1325-
foreach (var tag in GetVariableTags())
1298+
if (baseParam.IsOptional)
13261299
{
1327-
var service = makeServiceBindData.GetContextual($"{tag}{paramName}");
1328-
1329-
if (!CanMake(service))
1330-
{
1331-
continue;
1332-
}
1333-
1334-
var instance = Make(service);
1335-
if (ChangeType(ref instance, paramType))
1336-
{
1337-
return instance;
1338-
}
1300+
return baseParam.DefaultValue;
13391301
}
13401302

1341-
return null;
1303+
throw MakeUnresolvablePrimitiveException(baseParam.Name, baseParam.Member.DeclaringType);
13421304
}
13431305

13441306
/// <summary>
13451307
/// 获取变量标签
13461308
/// </summary>
13471309
/// <returns>变量标签</returns>
1348-
protected virtual char[] GetVariableTags()
1310+
protected virtual char GetVariableTag()
13491311
{
1350-
return new[] { '$', '@' };
1312+
return '$';
13511313
}
13521314

13531315
/// <summary>

0 commit comments

Comments
 (0)