Skip to content

Commit

Permalink
Merge pull request #596 from DenisPimenov/bugfix/open-generic
Browse files Browse the repository at this point in the history
Open generic bugfixes
  • Loading branch information
hadashiA authored Dec 19, 2023
2 parents c2087dc + 55cd12a commit c2d19a7
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
</PropertyGroup>

<ItemGroup>
<Compile Include="..\VContainer\Assets\VContainer\Tests\**\*.cs" Exclude="&#xA;..\VContainer\Assets\VContainer\Tests\Unity\**\*.cs;&#xA;" />
<Compile Include="..\VContainer\Assets\Tests\**\*.cs" Exclude="&#xA;..\VContainer\Assets\Tests\Unity\**\*.cs;&#xA;" />
</ItemGroup>

<ItemGroup>
Expand Down
10 changes: 9 additions & 1 deletion VContainer/Assets/Tests/Fixtures.cs
Original file line number Diff line number Diff line change
Expand Up @@ -317,13 +317,21 @@ public HasGenericDependency(IGenericService<NoDependencyServiceA> service)
}
}

class GenericsService<T> : IGenericService<T>
class GenericsService<T> : IGenericService<T>, IDisposable
{
public readonly T ParameterService;

public bool Disposed { get; private set; }

public GenericsService(T parameterService)
{
ParameterService = parameterService;
Disposed = false;
}

public void Dispose()
{
Disposed = true;
}
}

Expand Down
34 changes: 34 additions & 0 deletions VContainer/Assets/Tests/ScopedContainerTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,40 @@ public void CreateScopeWithResolveSingleton()
Assert.That(singleton, Is.EqualTo(singleton2));
}

[Test]
public void CreateScopeWithResolveOpenGeneric()
{
var builder = new ContainerBuilder();
builder.Register<NoDependencyServiceA>(Lifetime.Transient);
builder.RegisterOpenGeneric(typeof(GenericsService<>), Lifetime.Singleton)
.AsImplementedInterfaces()
.AsSelf();

builder.RegisterOpenGeneric(typeof(GenericsService2<,>), Lifetime.Singleton)
.AsImplementedInterfaces()
.AsSelf();

var container = builder.Build();
var scopedContainer = container.CreateScope(childBuilder =>
{
childBuilder.RegisterOpenGeneric(typeof(GenericsService<>), Lifetime.Singleton)
.AsImplementedInterfaces()
.AsSelf();
});

var singleton = container.Resolve<GenericsService<NoDependencyServiceA>>();
var singleton2 = scopedContainer.Resolve<GenericsService<NoDependencyServiceA>>();
var singleton3 = container.Resolve<GenericsService2<int,NoDependencyServiceA>>();
var singleton4 = scopedContainer.Resolve<GenericsService2<int,NoDependencyServiceA>>();

Assert.AreNotSame(singleton, singleton2);
Assert.AreSame(singleton3, singleton4);

scopedContainer.Dispose();

Assert.True(singleton2.Disposed);
}

[Test]
public void CreateScopeWithRegisterSingleton()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,19 @@ public override Registration Build()
return new Registration(ImplementationType, Lifetime, InterfaceTypes, provider);
}

public override RegistrationBuilder AsImplementedInterfaces()
{
InterfaceTypes = InterfaceTypes ?? new List<Type>();
foreach (var i in ImplementationType.GetInterfaces())
{
if (!i.IsGenericType)
continue;

InterfaceTypes.Add(i.GetGenericTypeDefinition());
}
return this;
}

protected override void AddInterfaceType(Type interfaceType)
{
if (interfaceType.IsConstructedGenericType)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public RegistrationBuilder AsSelf()
return this;
}

public RegistrationBuilder AsImplementedInterfaces()
public virtual RegistrationBuilder AsImplementedInterfaces()
{
InterfaceTypes = InterfaceTypes ?? new List<Type>();
InterfaceTypes.AddRange(ImplementationType.GetInterfaces());
Expand Down
13 changes: 12 additions & 1 deletion VContainer/Assets/VContainer/Runtime/Registry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,18 @@ bool TryGetClosedGenericRegistration(Type interfaceType, Type openGenericType,
return false;
}

public bool Exists(Type type) => hashTable.TryGet(type, out _);
public bool Exists(Type type)
{
if (hashTable.TryGet(type, out _))
return true;

if (type.IsConstructedGenericType)
{
type = RuntimeTypeCache.OpenGenericTypeOf(type);
}

return hashTable.TryGet(type, out _);
}

bool TryFallbackToContainerLocal(
Type closedGenericType,
Expand Down

1 comment on commit c2d19a7

@vercel
Copy link

@vercel vercel bot commented on c2d19a7 Dec 19, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.