Skip to content

Commit 07df279

Browse files
committed
Resolving issue with Optional Generic Parameter
Fixed #293
1 parent e65799e commit 07df279

File tree

6 files changed

+51
-16
lines changed

6 files changed

+51
-16
lines changed

package.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project>
22

33
<PropertyGroup>
4-
<VersionBase>5.11.9</VersionBase>
4+
<VersionBase>5.11.10</VersionBase>
55
<PackageReleaseNotes>This package is compatible with .NET Standard 1.0 and 2.0, .NET Core 1.0 and 2.0, .NET 4.0, 4.5, 4.6, 4.7</PackageReleaseNotes>
66
</PropertyGroup>
77

src/Processors/Abstracts/MemberExpression.cs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,15 @@ public abstract partial class MemberProcessor<TMemberInfo, TData> where TMemberI
1212

1313
protected virtual IEnumerable<Expression> ExpressionsFromSelection(Type type, IEnumerable<object> members)
1414
{
15+
HashSet<TMemberInfo> memberSet = new HashSet<TMemberInfo>();
16+
1517
foreach (var member in members)
1618
{
17-
1819
switch (member)
1920
{
2021
// TMemberInfo
2122
case TMemberInfo info:
23+
if (!memberSet.Add(info)) continue;
2224
object value = DependencyAttribute.Instance;
2325
foreach (var node in AttributeFactories)
2426
{
@@ -34,8 +36,9 @@ protected virtual IEnumerable<Expression> ExpressionsFromSelection(Type type, IE
3436

3537
// Injection Member
3638
case InjectionMember<TMemberInfo, TData> injectionMember:
37-
yield return GetResolverExpression(injectionMember.MemberInfo(type),
38-
injectionMember.Data);
39+
var selection = injectionMember.MemberInfo(type);
40+
if (!memberSet.Add(selection)) continue;
41+
yield return GetResolverExpression(selection, injectionMember.Data);
3942
break;
4043

4144
// Unknown

src/Processors/Abstracts/MemberProcessor.cs

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -154,8 +154,8 @@ public override IEnumerable<Expression> GetExpressions(Type type, IPolicySet reg
154154
public override ResolveDelegate<BuilderContext> GetResolver(Type type, IPolicySet registration, ResolveDelegate<BuilderContext> seed)
155155
{
156156
var selector = GetPolicy<ISelect<TMemberInfo>>(registration);
157-
var members = selector.Select(type, registration);
158-
var resolvers = ResolversFromSelection(type, members).ToArray();
157+
var members = selector.Select(type, registration);
158+
var resolvers = ResolversFromSelection(type, members).Distinct().ToArray();
159159

160160
return (ref BuilderContext c) =>
161161
{
@@ -172,14 +172,12 @@ public override ResolveDelegate<BuilderContext> GetResolver(Type type, IPolicySe
172172

173173
public virtual IEnumerable<object> Select(Type type, IPolicySet registration)
174174
{
175-
HashSet<object> memberSet = new HashSet<object>();
176-
177175
// Select Injected Members
178176
if (null != ((InternalRegistration)registration).InjectionMembers)
179177
{
180178
foreach (var injectionMember in ((InternalRegistration)registration).InjectionMembers)
181179
{
182-
if (injectionMember is InjectionMember<TMemberInfo, TData> && memberSet.Add(injectionMember))
180+
if (injectionMember is InjectionMember<TMemberInfo, TData>)
183181
yield return injectionMember;
184182
}
185183
}
@@ -193,12 +191,10 @@ public virtual IEnumerable<object> Select(Type type, IPolicySet registration)
193191
for (var i = 0; i < AttributeFactories.Length; i++)
194192
{
195193
#if NET40
196-
if (!member.IsDefined(AttributeFactories[i].Type, true) ||
194+
if (!member.IsDefined(AttributeFactories[i].Type, true)) continue;
197195
#else
198-
if (!member.IsDefined(AttributeFactories[i].Type) ||
196+
if (!member.IsDefined(AttributeFactories[i].Type)) continue;
199197
#endif
200-
!memberSet.Add(member)) continue;
201-
202198
yield return member;
203199
break;
204200
}

src/Processors/Abstracts/MemberResolution.cs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
using System.Reflection;
44
using Unity.Builder;
55
using Unity.Injection;
6-
using Unity.Policy;
76
using Unity.Resolution;
87

98
namespace Unity.Processors
@@ -14,12 +13,15 @@ public abstract partial class MemberProcessor<TMemberInfo, TData> where TMemberI
1413

1514
protected virtual IEnumerable<ResolveDelegate<BuilderContext>> ResolversFromSelection(Type type, IEnumerable<object> members)
1615
{
16+
HashSet<TMemberInfo> memberSet = new HashSet<TMemberInfo>();
17+
1718
foreach (var member in members)
1819
{
1920
switch (member)
2021
{
2122
// MemberInfo
2223
case TMemberInfo info:
24+
if (!memberSet.Add(info)) continue;
2325
object value = DependencyAttribute.Instance;
2426
foreach (var node in AttributeFactories)
2527
{
@@ -34,8 +36,9 @@ protected virtual IEnumerable<ResolveDelegate<BuilderContext>> ResolversFromSele
3436

3537
// Injection Member
3638
case InjectionMember<TMemberInfo, TData> injectionMember:
37-
yield return GetResolverDelegate(injectionMember.MemberInfo(type),
38-
injectionMember.Data);
39+
var selection = injectionMember.MemberInfo(type);
40+
if (!memberSet.Add(selection)) continue;
41+
yield return GetResolverDelegate(selection, injectionMember.Data);
3942
break;
4043

4144
// Unknown

src/Processors/Methods/MethodProcessor.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ protected override IEnumerable<MethodInfo> DeclaredMembers(Type type)
3434

3535
#endregion
3636

37+
3738
#region Expression
3839

3940
protected override Expression GetResolverExpression(MethodInfo info, object resolvers)

tests/Unity.Tests/Issues/GitHub.cs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using Microsoft.VisualStudio.TestTools.UnitTesting;
22
using System;
33
using System.Diagnostics;
4+
using Unity.Injection;
45
using Unity.Lifetime;
56
using Unity.Resolution;
67

@@ -222,6 +223,37 @@ public void unitycontainer_container_82()
222223
Assert.AreEqual(main2, main2.HelperClass.HostClass);
223224
}
224225

226+
public class BaselineTestType<TDependency>
227+
{
228+
[Dependency] public TDependency Field;
229+
230+
public object Value { get => Field; protected set => throw new NotSupportedException(); }
231+
public object Expected => default(TDependency);
232+
}
233+
234+
[TestMethod]
235+
public void unitycontainer_container_293()
236+
{
237+
var unnamed = 55;
238+
var named = 22;
239+
var name = "Name";
240+
241+
// Create root container and register classes in root
242+
IUnityContainer container = new UnityContainer();
243+
244+
container.RegisterType(typeof(BaselineTestType<>), new InjectionField("Field", new OptionalGenericParameter("TDependency", name)));
245+
246+
var instance = container.Resolve<BaselineTestType<int>>();
247+
Assert.IsNotNull(instance);
248+
Assert.AreEqual(0, instance.Field);
249+
250+
container.RegisterInstance(unnamed)
251+
.RegisterInstance(name, named);
252+
253+
instance = container.Resolve<BaselineTestType<int>>();
254+
Assert.IsNotNull(instance);
255+
Assert.AreEqual(named, instance.Field);
256+
}
225257
}
226258

227259
public class MainClass : IHostClass

0 commit comments

Comments
 (0)