Skip to content

Commit 8a9d6cb

Browse files
authored
Merge pull request #69 from mewlist/prefab-factory-accepts-args
PrefabFactory accepts args type parameter.
2 parents 658bf09 + 5238472 commit 8a9d6cb

File tree

9 files changed

+122
-12
lines changed

9 files changed

+122
-12
lines changed

Runtime/Binder/PrefabBinder.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,5 +82,10 @@ public FactoryBinder<T, Factory<T>> AsFactory()
8282
{
8383
return new FactoryBinder<T, Factory<T>>(context, AsTransient());
8484
}
85+
86+
public FactoryBinder<T, Factory<TArg1, T>> AsFactory<TArg1>() => new(context, AsTransient());
87+
public FactoryBinder<T, Factory<TArg1, TArg2, T>> AsFactory<TArg1, TArg2>() => new(context, AsTransient());
88+
public FactoryBinder<T, Factory<TArg1, TArg2, TArg3, T>> AsFactory<TArg1, TArg2, TArg3>() => new(context, AsTransient());
89+
public FactoryBinder<T, Factory<TArg1, TArg2, TArg3, TArg4, T>> AsFactory<TArg1, TArg2, TArg3, TArg4>() => new(context, AsTransient());
8590
}
8691
}

Runtime/Resolver/AbstractInternalResolver.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System.Threading.Tasks;
1+
using System.Linq;
2+
using System.Threading.Tasks;
23

34
namespace Doinject
45
{
@@ -25,5 +26,13 @@ public async ValueTask<object> ResolveAsObjectAsync(DIContainer container)
2526
public abstract ValueTask<T> ResolveAsync(IReadOnlyDIContainer container, object[] args = null);
2627

2728
public abstract ValueTask DisposeAsync();
29+
30+
protected object[] CombineArgs(object[] args1, object[] args2)
31+
{
32+
if (args1 == null && args2 == null) return null;
33+
if (args1 == null) return args2;
34+
if (args2 == null) return args1;
35+
return args1.Concat(args2).ToArray();
36+
}
2837
}
2938
}

Runtime/Resolver/CustomFactoryResolver.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public override async ValueTask<TFactory> ResolveAsync(IReadOnlyDIContainer cont
3030
CachingCompletionSource = new MewCompletionSource();
3131

3232
var instance = await container.InstantiateAsync<TFactory>(
33-
Args ?? args,
33+
CombineArgs(Args, args),
3434
Array.Empty<ScopedInstance>());
3535
InstanceBag.Add(TargetType, instance);
3636
CachingCompletionSource?.TrySetResult();

Runtime/Resolver/MonoBahaviourResolver.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ private async ValueTask<T> Instantiate(IReadOnlyDIContainer container, object[]
6969
if (Under)
7070
return await container.InstantiateMonoBehaviourAsync<TInstance>(Under, WorldPositionStays, Args);
7171

72-
return await container.InstantiateMonoBehaviourAsync<TInstance>(On, Args ?? args);
72+
return await container.InstantiateMonoBehaviourAsync<TInstance>(On, CombineArgs(Args, args));
7373
}
7474

7575
public async Task TryCacheAsync(DIContainer container)

Runtime/Resolver/PrefabResolver.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ public override async ValueTask<T> ResolveAsync(IReadOnlyDIContainer container,
6060

6161
private async ValueTask<T> Instantiate(IReadOnlyDIContainer container, object[] args)
6262
{
63-
var instance = (T)await container.InstantiatePrefabAsync(TargetType.Type, Args ?? args, Prefab);
63+
var instance = (T)await container.InstantiatePrefabAsync(TargetType.Type, CombineArgs(Args, args), Prefab);
6464

6565
if (Under && instance is Component component)
6666
component.transform.SetParent(Under, WorldPositionStays);

Runtime/Resolver/TypeResolver.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ public override async ValueTask<T> ResolveAsync(IReadOnlyDIContainer container,
4747

4848
private async ValueTask<T> Instantiate(IReadOnlyDIContainer container, object[] args)
4949
{
50-
var instance = await container.InstantiateAsync<TInstance>(Args ?? args);
50+
var instance = await container.InstantiateAsync<TInstance>(CombineArgs(Args, args));
5151
return instance;
5252
}
5353

Tests/Components/TestMonoBehaviour.cs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,24 @@
1-
using UnityEngine;
1+
using System.Collections.Generic;
2+
using UnityEngine;
23

34
namespace Doinject.Tests
45
{
56
public class TestMonoBehaviour : MonoBehaviour, IInjectableComponent
67
{
7-
public InjectedObject InjectedObject { get; private set; }
8+
public List<InjectedObject> InjectedObjects { get; private set; } = new();
89
public int InjectedCount { get; private set; }
910

1011
[Inject]
11-
public void Inject(InjectedObject injectedObject)
12+
public void Inject(
13+
InjectedObject injectedObject,
14+
[Optional] InjectedObject injectedObject2,
15+
[Optional] InjectedObject injectedObject3,
16+
[Optional] InjectedObject injectedObject4)
1217
{
13-
InjectedObject = injectedObject;
18+
InjectedObjects.Add(injectedObject);
19+
InjectedObjects.Add(injectedObject2);
20+
InjectedObjects.Add(injectedObject3);
21+
InjectedObjects.Add(injectedObject4);
1422
InjectedCount++;
1523
}
1624
}

Tests/ContextTest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ public async Task CreateGameObjectContextTest()
5757
Assert.That(Object.FindFirstObjectByType<GameObjectContext>(), Is.EqualTo(goContext));
5858

5959
var testComponent = Object.FindFirstObjectByType<TestMonoBehaviour>();
60-
Assert.That(testComponent.InjectedObject, Is.Not.Null);
60+
Assert.That(testComponent.InjectedObjects[0], Is.Not.Null);
6161
}
6262
}
6363
}

Tests/FactoryTest.cs

Lines changed: 90 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ public async Task MonoBehaviourFactoryWithArgsTest()
162162
var instance = await factory.CreateAsync();
163163
Assert.That(instance, Is.TypeOf<TestMonoBehaviour>());
164164
Assert.That((instance as TestMonoBehaviour)?.gameObject, Is.EqualTo(gameObject));
165-
Assert.That((instance as TestMonoBehaviour)?.InjectedObject, Is.EqualTo(injectedObject));
165+
Assert.That((instance as TestMonoBehaviour)?.InjectedObjects[0], Is.EqualTo(injectedObject));
166166
}
167167

168168
[Test]
@@ -197,7 +197,95 @@ public async Task PrefabFactoryWithArgsTest()
197197

198198
var factory = await container.ResolveAsync<Factory<TestMonoBehaviour>>();
199199
var instance = await factory.CreateAsync();
200-
Assert.That(instance.InjectedObject, Is.EqualTo(injectedInstance));
200+
Assert.That(instance.InjectedObjects[0], Is.EqualTo(injectedInstance));
201+
Assert.That(instance.InjectedObjects[1], Is.Null);
202+
Assert.That(instance.InjectedObjects[2], Is.Null);
203+
Assert.That(instance.InjectedObjects[3], Is.Null);
204+
}
205+
206+
[Test]
207+
public async Task PrefabFactoryWithMultiArgsTest()
208+
{
209+
const string prefabGuid = "b1f3d745bc6e3624b852543a31febb12";
210+
var prefabPath = AssetDatabase.GUIDToAssetPath(prefabGuid);
211+
var prefab = AssetDatabase.LoadAssetAtPath<TestMonoBehaviour>(prefabPath);
212+
213+
var injectedInstances = new[] { new InjectedObject(), new InjectedObject(), new InjectedObject(), new InjectedObject() };
214+
container
215+
.BindPrefab<TestMonoBehaviour>(prefab)
216+
.Args(injectedInstances[0], injectedInstances[1], injectedInstances[2], injectedInstances[3])
217+
.AsFactory();
218+
219+
var factory = await container.ResolveAsync<Factory<TestMonoBehaviour>>();
220+
var instance = await factory.CreateAsync();
221+
Assert.That(instance.InjectedObjects[0], Is.EqualTo(injectedInstances[0]));
222+
Assert.That(instance.InjectedObjects[1], Is.EqualTo(injectedInstances[1]));
223+
Assert.That(instance.InjectedObjects[2], Is.EqualTo(injectedInstances[2]));
224+
Assert.That(instance.InjectedObjects[3], Is.EqualTo(injectedInstances[3]));
225+
}
226+
227+
[Test]
228+
public async Task SingleArgsPrefabFactoryTest()
229+
{
230+
const string prefabGuid = "b1f3d745bc6e3624b852543a31febb12";
231+
var prefabPath = AssetDatabase.GUIDToAssetPath(prefabGuid);
232+
var prefab = AssetDatabase.LoadAssetAtPath<TestMonoBehaviour>(prefabPath);
233+
234+
var injectedInstance = new InjectedObject();
235+
236+
container
237+
.BindPrefab<TestMonoBehaviour>(prefab)
238+
.AsFactory<InjectedObject>();
239+
240+
var factory = await container.ResolveAsync<Factory<InjectedObject, TestMonoBehaviour>>();
241+
var instance = await factory.CreateAsync(injectedInstance);
242+
Assert.That(instance.InjectedObjects[0], Is.EqualTo(injectedInstance));
243+
Assert.That(instance.InjectedObjects[1], Is.Null);
244+
Assert.That(instance.InjectedObjects[2], Is.Null);
245+
Assert.That(instance.InjectedObjects[3], Is.Null);
246+
}
247+
248+
[Test]
249+
public async Task MultiArgsPrefabFactoryTest()
250+
{
251+
const string prefabGuid = "b1f3d745bc6e3624b852543a31febb12";
252+
var prefabPath = AssetDatabase.GUIDToAssetPath(prefabGuid);
253+
var prefab = AssetDatabase.LoadAssetAtPath<TestMonoBehaviour>(prefabPath);
254+
255+
var injectedInstances = new[] { new InjectedObject(), new InjectedObject(), new InjectedObject(), new InjectedObject() };
256+
257+
container
258+
.BindPrefab<TestMonoBehaviour>(prefab)
259+
.AsFactory<InjectedObject, InjectedObject, InjectedObject, InjectedObject>();
260+
261+
var factory = await container.ResolveAsync<Factory<InjectedObject, InjectedObject, InjectedObject, InjectedObject, TestMonoBehaviour>>();
262+
var instance = await factory.CreateAsync(injectedInstances[0], injectedInstances[1], injectedInstances[2], injectedInstances[3]);
263+
Assert.That(instance.InjectedObjects[0], Is.EqualTo(injectedInstances[0]));
264+
Assert.That(instance.InjectedObjects[1], Is.EqualTo(injectedInstances[1]));
265+
Assert.That(instance.InjectedObjects[2], Is.EqualTo(injectedInstances[2]));
266+
Assert.That(instance.InjectedObjects[3], Is.EqualTo(injectedInstances[3]));
267+
}
268+
269+
[Test]
270+
public async Task MixedArgsPrefabFactoryTest()
271+
{
272+
const string prefabGuid = "b1f3d745bc6e3624b852543a31febb12";
273+
var prefabPath = AssetDatabase.GUIDToAssetPath(prefabGuid);
274+
var prefab = AssetDatabase.LoadAssetAtPath<TestMonoBehaviour>(prefabPath);
275+
276+
var injectedInstances = new[] { new InjectedObject(), new InjectedObject(), new InjectedObject(), new InjectedObject() };
277+
278+
container
279+
.BindPrefab<TestMonoBehaviour>(prefab)
280+
.Args(injectedInstances[0])
281+
.AsFactory<InjectedObject, InjectedObject, InjectedObject>();
282+
283+
var factory = await container.ResolveAsync<Factory<InjectedObject, InjectedObject, InjectedObject, TestMonoBehaviour>>();
284+
var instance = await factory.CreateAsync(injectedInstances[1], injectedInstances[2], injectedInstances[3]);
285+
Assert.That(instance.InjectedObjects[0], Is.EqualTo(injectedInstances[0]));
286+
Assert.That(instance.InjectedObjects[1], Is.EqualTo(injectedInstances[1]));
287+
Assert.That(instance.InjectedObjects[2], Is.EqualTo(injectedInstances[2]));
288+
Assert.That(instance.InjectedObjects[3], Is.EqualTo(injectedInstances[3]));
201289
}
202290

203291
[TestCase(9)]

0 commit comments

Comments
 (0)