Added ScopeFactory property to the Factory class to expose IServiceScopeFactory through GetRequiredService<IServiceScopeFactory>(). This enables scoped service creation from the factory instance.
142 lines
3.7 KiB
C#
142 lines
3.7 KiB
C#
using Microsoft.Extensions.DependencyInjection;
|
|
using System.Collections;
|
|
#if NETFRAMEWORK
|
|
using System;
|
|
using System.Collections.Generic;
|
|
#endif
|
|
|
|
namespace DigitalData.Core.Abstractions
|
|
{
|
|
public class Factory : IServiceProvider, IServiceCollection
|
|
{
|
|
public static readonly Factory Shared = new Factory();
|
|
|
|
private readonly IServiceCollection _serviceCollection = new ServiceCollection();
|
|
private readonly Lazy<IServiceProvider> _lazyServiceProvider;
|
|
|
|
private bool IsBuilt => _lazyServiceProvider.IsValueCreated;
|
|
|
|
private PostBuildBehavior _pbBehavior = PostBuildBehavior.ThrowException;
|
|
|
|
public Factory BehaveOnPostBuild(PostBuildBehavior postBuildBehavior)
|
|
{
|
|
_pbBehavior = postBuildBehavior;
|
|
return this;
|
|
}
|
|
|
|
public Factory()
|
|
{
|
|
_lazyServiceProvider = new Lazy<IServiceProvider>(() => _serviceCollection.BuildServiceProvider());
|
|
}
|
|
|
|
#region Service Provider
|
|
public object
|
|
#if NET
|
|
?
|
|
#endif
|
|
GetService(Type serviceType)
|
|
{
|
|
return _lazyServiceProvider.Value.GetService(serviceType);
|
|
}
|
|
|
|
public IServiceScopeFactory ScopeFactory => this.GetRequiredService<IServiceScopeFactory>();
|
|
#endregion
|
|
|
|
#region Service Collection
|
|
public int Count => _serviceCollection.Count;
|
|
|
|
public bool IsReadOnly => _serviceCollection.IsReadOnly;
|
|
|
|
public ServiceDescriptor this[int index]
|
|
{
|
|
get => _serviceCollection[index];
|
|
set
|
|
{
|
|
if (EnsureBuilt())
|
|
return;
|
|
_serviceCollection[index] = value;
|
|
}
|
|
}
|
|
|
|
public int IndexOf(ServiceDescriptor item)
|
|
{
|
|
return _serviceCollection.IndexOf(item);
|
|
}
|
|
|
|
public void Insert(int index, ServiceDescriptor item)
|
|
{
|
|
if (EnsureBuilt())
|
|
return;
|
|
_serviceCollection.Insert(index, item);
|
|
}
|
|
|
|
public void RemoveAt(int index)
|
|
{
|
|
if (EnsureBuilt())
|
|
return;
|
|
_serviceCollection.RemoveAt(index);
|
|
}
|
|
|
|
public void Add(ServiceDescriptor item)
|
|
{
|
|
if (EnsureBuilt())
|
|
return;
|
|
_serviceCollection.Add(item);
|
|
}
|
|
|
|
public void Clear()
|
|
{
|
|
if (EnsureBuilt())
|
|
return;
|
|
_serviceCollection.Clear();
|
|
}
|
|
|
|
public bool Contains(ServiceDescriptor item)
|
|
{
|
|
return _serviceCollection.Contains(item);
|
|
}
|
|
|
|
public void CopyTo(ServiceDescriptor[] array, int arrayIndex)
|
|
{
|
|
_serviceCollection.CopyTo(array, arrayIndex);
|
|
}
|
|
|
|
public bool Remove(ServiceDescriptor item)
|
|
{
|
|
if (EnsureBuilt())
|
|
return false;
|
|
return _serviceCollection.Remove(item);
|
|
}
|
|
|
|
public IEnumerator<ServiceDescriptor> GetEnumerator()
|
|
{
|
|
return _serviceCollection.GetEnumerator();
|
|
}
|
|
|
|
IEnumerator IEnumerable.GetEnumerator()
|
|
{
|
|
return (_serviceCollection as IEnumerable).GetEnumerator();
|
|
}
|
|
#endregion
|
|
|
|
#region Helpers
|
|
private bool EnsureBuilt()
|
|
{
|
|
if (IsBuilt)
|
|
{
|
|
return _pbBehavior == PostBuildBehavior.ThrowException
|
|
? throw new InvalidOperationException("Service provider has already been built. No further service modifications are allowed.")
|
|
: true;
|
|
}
|
|
else
|
|
return false;
|
|
}
|
|
#endregion
|
|
}
|
|
|
|
public enum PostBuildBehavior
|
|
{
|
|
ThrowException,
|
|
Ignore
|
|
}
|
|
} |