Skip to content

Commit

Permalink
adding CreateScope
Browse files Browse the repository at this point in the history
  • Loading branch information
dansiegel committed Apr 24, 2020
1 parent 0cb5b2e commit 4d898d4
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 2 deletions.
54 changes: 53 additions & 1 deletion src/Containers/Prism.DryIoc.Shared/DryIocContainerExtension.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.Linq;
using DryIoc;
using Prism.Ioc;
Expand All @@ -11,6 +11,8 @@ namespace Prism.DryIoc
/// </summary>
public class DryIocContainerExtension : IContainerExtension<IContainer>, IContainerInfo
{
private ServiceScope _currentScope;

/// <summary>
/// The instance of the wrapped container
/// </summary>
Expand Down Expand Up @@ -183,5 +185,55 @@ Type IContainerInfo.GetRegistrationType(string key)

return matchingRegistration.ImplementationType;
}

/// <summary>
/// Creates a new Scope
/// </summary>
public virtual void CreateScope() =>
CreateScopeInternal();

/// <summary>
/// Creates a new Scope and provides the updated ServiceProvider
/// </summary>
/// <returns>The Scoped <see cref="IServiceProvider" />.</returns>
/// <remarks>
/// This should be called by custom implementations that Implement IServiceScopeFactory
/// </remarks>
protected IServiceProvider CreateScopeInternal()
{
if (_currentScope != null)
{
_currentScope.Dispose();
_currentScope = null;
GC.Collect();
}

_currentScope = new ServiceScope(Instance.OpenScope());
return _currentScope;
}

private class ServiceScope : IServiceProvider, IDisposable
{
public ServiceScope(IResolverContext context)
{
Context = context;
}

public IResolverContext Context { get; private set; }

public object GetService(Type serviceType) =>
Context.GetService(serviceType);

public void Dispose()
{
if (Context != null)
{
Context.Dispose();
Context = null;
}

GC.Collect();
}
}
}
}
62 changes: 61 additions & 1 deletion src/Containers/Prism.Unity.Shared/UnityContainerExtension.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
using System;
using System;
using System.Linq;
using Prism.Ioc;
using Prism.Ioc.Internals;
using Unity;
using Unity.Lifetime;
using Unity.Resolution;

namespace Prism.Unity
Expand All @@ -12,6 +13,8 @@ namespace Prism.Unity
/// </summary>
public class UnityContainerExtension : IContainerExtension<IUnityContainer>, IContainerInfo
{
private ServiceScope _currentScope;

/// <summary>
/// The instance of the wrapped container
/// </summary>
Expand Down Expand Up @@ -196,5 +199,62 @@ Type IContainerInfo.GetRegistrationType(string key)

return matchingRegistration?.MappedToType;
}

/// <summary>
/// Creates a new Scope
/// </summary>
public virtual void CreateScope() =>
CreateScopeInternal();

/// <summary>
/// Creates a new Scope and provides the updated ServiceProvider
/// </summary>
/// <returns>The Scoped <see cref="IServiceProvider" />.</returns>
/// <remarks>
/// This should be called by custom implementations that Implement IServiceScopeFactory
/// </remarks>
protected IServiceProvider CreateScopeInternal()
{
if (_currentScope != null)
{
_currentScope.Dispose();
_currentScope = null;
GC.Collect();
}

_currentScope = new ServiceScope(Instance.CreateChildContainer());
return _currentScope;
}

private class ServiceScope : IServiceProvider//, IServiceScope
{
public ServiceScope(IUnityContainer container)
{
Container = container;
}

public IUnityContainer Container { get; private set; }

public IServiceProvider ServiceProvider => this;

public object GetService(Type serviceType)
{
if (!Container.IsRegistered(serviceType))
return null;

return Container.Resolve(serviceType);
}

public void Dispose()
{
if (Container != null)
{
Container.Dispose();
Container = null;
}

GC.Collect();
}
}
}
}
5 changes: 5 additions & 0 deletions src/Prism.Core/Ioc/IContainerProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,10 @@ public interface IContainerProvider
/// <param name="parameters">Typed parameters to use when resolving the Service</param>
/// <returns>The resolved Service <see cref="Type"/></returns>
object Resolve(Type type, string name, params (Type Type, object Instance)[] parameters);

/// <summary>
/// Creates a new scope
/// </summary>
void CreateScope();
}
}

0 comments on commit 4d898d4

Please sign in to comment.