Skip to content

Commit

Permalink
Implemented IServiceProviderIsService (#33)
Browse files Browse the repository at this point in the history
  • Loading branch information
CoryCharlton authored Nov 6, 2023
1 parent f43b8b3 commit a09fbd7
Show file tree
Hide file tree
Showing 37 changed files with 185 additions and 64 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
using System;
using System.Reflection;

namespace nanoFramework.DependencyInjection
namespace Microsoft.Extensions.DependencyInjection
{
/// <summary>
/// Helper code for the various activator services.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

using System.Collections;

namespace nanoFramework.DependencyInjection
namespace Microsoft.Extensions.DependencyInjection
{
/// <summary>
/// Default implementation of IServiceCollection.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using System;

namespace Microsoft.Extensions.DependencyInjection
{
/// <summary>
/// Optional service used to determine if the specified type is available from the <see cref="IServiceProvider"/>.
/// </summary>
public interface IServiceProviderIsService
{
/// <summary>
/// Determines if the specified service type is available from the <see cref="IServiceProvider"/>.
/// </summary>
/// <param name="serviceType">An object that specifies the type of service object to test.</param>
/// <returns>true if the specified service is a available, false if it is not.</returns>
bool IsService(Type serviceType);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

using System;

namespace nanoFramework.DependencyInjection
namespace Microsoft.Extensions.DependencyInjection
{
/// <summary>
/// Defines scope for <see cref="IServiceProvider"/>.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@

using System.Collections;

namespace nanoFramework.DependencyInjection
namespace Microsoft.Extensions.DependencyInjection
{
/// <summary>
/// Default implementation of <see cref="IServiceCollection"/>.
/// </summary>
public class ServiceCollection : IServiceCollection
{
private static readonly object _syncLock = new object();
private readonly ArrayList _descriptors = new ArrayList();
private static readonly object _syncLock = new();
private readonly ArrayList _descriptors = new();

/// <inheritdoc/>
public bool IsReadOnly => false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// See LICENSE file in the project root for full license information.
//

namespace nanoFramework.DependencyInjection
namespace Microsoft.Extensions.DependencyInjection
{
/// <summary>
/// Extension methods for building a <see cref="ServiceProvider"/> from an <see cref="IServiceCollection"/>.
Expand All @@ -17,7 +17,7 @@ public static class ServiceCollectionContainerBuilderExtensions
/// <returns>The <see cref="ServiceProvider"/>.</returns>
public static ServiceProvider BuildServiceProvider(this IServiceCollection services)
{
return BuildServiceProvider(services, ServiceProviderOptions.Default);
return services.BuildServiceProvider(ServiceProviderOptions.Default);
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
using System;
using System.Collections;

namespace nanoFramework.DependencyInjection
namespace Microsoft.Extensions.DependencyInjection
{
/// <summary>
/// Extensions for <see cref="IServiceCollection"/>.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
using System;
using System.Diagnostics;

namespace nanoFramework.DependencyInjection
namespace Microsoft.Extensions.DependencyInjection
{
/// <summary>
/// Describes a service with its service type, implementation, and lifetime.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// See LICENSE file in the project root for full license information.
//

namespace nanoFramework.DependencyInjection
namespace Microsoft.Extensions.DependencyInjection
{
/// <summary>
/// Specifies the lifetime of a service in an <see cref="IServiceCollection"/>.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@
using System;
using System.Collections;

namespace nanoFramework.DependencyInjection
namespace Microsoft.Extensions.DependencyInjection
{
/// <summary>
/// The default <see cref="IServiceProvider"/>.
/// </summary>
/// <exception cref="AggregateException">Some services are not able to be constructed.</exception>
public sealed class ServiceProvider : IServiceProvider, IDisposable
public sealed class ServiceProvider : IServiceProvider, IServiceProviderIsService, IDisposable
{
private bool _disposed;

Expand Down Expand Up @@ -103,5 +103,11 @@ private ServiceProviderEngine GetEngine()
{
return ServiceProviderEngine.Instance;
}

/// <inheritdoc />
public bool IsService(Type serviceType)
{
return Engine.IsService(serviceType);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
using System.Reflection;
using System.Collections;

namespace nanoFramework.DependencyInjection
namespace Microsoft.Extensions.DependencyInjection
{
/// <summary>
/// Defines an engine for managing <see cref="IServiceCollection"/> services that provides custom support to other objects.
Expand Down Expand Up @@ -144,7 +144,7 @@ private object[] GetServiceObjects(Type serviceType, IServiceCollection scopeSer
foreach (ServiceDescriptor descriptor in Services)
{
if (descriptor.ServiceType != serviceType) continue;

switch (descriptor.Lifetime)
{
case ServiceLifetime.Singleton:
Expand All @@ -158,7 +158,9 @@ private object[] GetServiceObjects(Type serviceType, IServiceCollection scopeSer

case ServiceLifetime.Scoped:
if (scopeServices == null && Options.ValidateScopes)
{
throw new InvalidOperationException();
}
break;
}
}
Expand Down Expand Up @@ -224,7 +226,7 @@ private object Resolve(Type implementationType)
}

/// <summary>
/// Gets the parameters from the constructor with the most parameters.
/// Gets the parameters from the constructor with the most parameters that can be resolved.
/// </summary>
/// <param name="implementationType">An object that specifies the implementation type of service object to get.</param>
/// <exception cref="InvalidOperationException">Multiple constructors accepting all given argument types have been found in type <paramref name="implementationType"/>. There should only be one applicable constructor.</exception>
Expand Down Expand Up @@ -263,10 +265,15 @@ private ParameterInfo[] GetParameters(Type implementationType)
{
// check for simple binding first
}
else if (GetService(type) == null)
else
{
// binding could not be resolved ingore constructor
length = -1;
if (!IsService(type))
{
// binding could not be resolved ignore constructor
length = -1;
break;
}

}
}

Expand Down Expand Up @@ -306,5 +313,23 @@ private static object GetResolvableDefault(Type type)

return null;
}

/// <summary>
/// Determines if the specified service type is available from the <see cref="IServiceCollection"/>.
/// </summary>
/// <param name="serviceType">An object that specifies the type of service object to test.</param>
/// <returns>true if the specified service is a available, false if it is not.</returns>
internal bool IsService(Type serviceType)
{
foreach (ServiceDescriptor descriptor in Services)
{
if (descriptor.ServiceType == serviceType)
{
return true;
}
}

return false;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@

using System;

namespace nanoFramework.DependencyInjection
namespace Microsoft.Extensions.DependencyInjection
{
/// <summary>
/// The <see cref="System.IDisposable.Dispose"/> method ends the scope lifetime. Once Dispose
/// The <see cref="IDisposable.Dispose"/> method ends the scope lifetime. Once Dispose
/// is called, any scoped services that have been resolved from
/// <see cref="IServiceProvider"/> will be disposed.
/// </summary>
Expand All @@ -22,7 +22,7 @@ internal sealed class ServiceProviderEngineScope : IServiceScope, IServiceProvid
/// The root service provider used to resolve dependencies from the scope.
/// </summary>
internal ServiceProvider RootProvider { get; }

/// <summary>
/// Creates instance of <see cref="ServiceProviderEngineScope"/>.
/// </summary>
Expand Down Expand Up @@ -75,7 +75,7 @@ public void Dispose()
return;
}

_disposed = true;
_disposed = true;
DisposeServices();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

using System;

namespace nanoFramework.DependencyInjection
namespace Microsoft.Extensions.DependencyInjection
{
/// <summary>
/// Options for configuring various behaviors of the default <see cref="IServiceProvider"/> implementation.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

using System;

namespace nanoFramework.DependencyInjection
namespace Microsoft.Extensions.DependencyInjection
{
/// <summary>
/// Extension methods for getting services from an <see cref="IServiceProvider" />.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
using System;
using System.Diagnostics;

namespace nanoFramework.DependencyInjection
namespace Microsoft.Extensions.DependencyInjection
{
/// <summary>
/// An <see cref="IServiceScope" /> implementation that implements <see cref="IDisposable" />.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using System;
using System.Collections;

namespace nanoFramework.DependencyInjection
namespace Microsoft.Extensions.DependencyInjection
{
/// <summary>
/// Contains extension methods for <see cref="Type"/>.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

// General Information about an assembly is controlled through the following
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<FileAlignment>512</FileAlignment>
<RootNamespace>nanoFramework.DependencyInjection</RootNamespace>
<AssemblyName>nanoFramework.DependencyInjection</AssemblyName>
<TargetFrameworkVersion>v1.0</TargetFrameworkVersion>
<NF_IsCoreLibrary>True</NF_IsCoreLibrary>
Expand All @@ -30,25 +29,26 @@
</PropertyGroup>
<Import Project="$(NanoFrameworkProjectSystemPath)NFProjectSystem.props" Condition="Exists('$(NanoFrameworkProjectSystemPath)NFProjectSystem.props')" />
<ItemGroup>
<Compile Include="DependencyInjection\ActivatorUtilities.cs" />
<Compile Include="DependencyInjection\IServiceCollection.cs" />
<Compile Include="DependencyInjection\ServiceScope.cs" />
<Compile Include="DependencyInjection\IServiceScope.cs" />
<Compile Include="DependencyInjection\ServiceProviderEngine.cs" />
<Compile Include="DependencyInjection\ServiceProviderEngineScope.cs" />
<Compile Include="DependencyInjection\TypeExtensions.cs" />
<Compile Include="Microsoft\Extensions\DependencyInjection\ActivatorUtilities.cs" />
<Compile Include="Microsoft\Extensions\DependencyInjection\IServiceCollection.cs" />
<Compile Include="Microsoft\Extensions\DependencyInjection\ServiceScope.cs" />
<Compile Include="Microsoft\Extensions\DependencyInjection\IServiceScope.cs" />
<Compile Include="Microsoft\Extensions\DependencyInjection\ServiceProviderEngine.cs" />
<Compile Include="Microsoft\Extensions\DependencyInjection\ServiceProviderEngineScope.cs" />
<Compile Include="Microsoft\Extensions\DependencyInjection\TypeExtensions.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="DependencyInjection\ServiceCollection.cs" />
<Compile Include="DependencyInjection\ServiceCollectionContainerBuilderExtensions.cs" />
<Compile Include="DependencyInjection\ServiceCollectionServiceExtensions.cs" />
<Compile Include="DependencyInjection\ServiceDescriptor.cs" />
<Compile Include="DependencyInjection\ServiceLifetime.cs" />
<Compile Include="DependencyInjection\ServiceProvider.cs" />
<Compile Include="DependencyInjection\ServiceProviderOptions.cs" />
<Compile Include="DependencyInjection\ServiceProviderServiceExtensions.cs" />
<Compile Include="Microsoft\Extensions\DependencyInjection\ServiceCollection.cs" />
<Compile Include="Microsoft\Extensions\DependencyInjection\ServiceCollectionContainerBuilderExtensions.cs" />
<Compile Include="Microsoft\Extensions\DependencyInjection\ServiceCollectionServiceExtensions.cs" />
<Compile Include="Microsoft\Extensions\DependencyInjection\ServiceDescriptor.cs" />
<Compile Include="Microsoft\Extensions\DependencyInjection\ServiceLifetime.cs" />
<Compile Include="Microsoft\Extensions\DependencyInjection\ServiceProvider.cs" />
<Compile Include="Microsoft\Extensions\DependencyInjection\ServiceProviderOptions.cs" />
<Compile Include="Microsoft\Extensions\DependencyInjection\ServiceProviderServiceExtensions.cs" />
<Compile Include="System\Activator.cs" />
<Compile Include="System\AggregateException.cs" />
<Compile Include="System\IServiceProvider.cs" />
<Compile Include="Microsoft\Extensions\DependencyInjection\IServiceProviderIsService.cs" />
</ItemGroup>
<ItemGroup>
<None Include="..\.editorconfig" Link=".editorconfig" />
Expand Down
1 change: 1 addition & 0 deletions tests/ActivatorUtilitiesTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System;
using nanoFramework.TestFramework;
using nanoFramework.DependencyInjection.UnitTests.Fakes;
using Microsoft.Extensions.DependencyInjection;

namespace nanoFramework.DependencyInjection.UnitTests
{
Expand Down
1 change: 1 addition & 0 deletions tests/DependencyInjectionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// See LICENSE file in the project root for full license information.
//

using Microsoft.Extensions.DependencyInjection;
using nanoFramework.DependencyInjection.UnitTests.Fakes;
using nanoFramework.TestFramework;
using System;
Expand Down
2 changes: 0 additions & 2 deletions tests/Fakes/FakeObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
// See LICENSE file in the project root for full license information.
//

using System;

namespace nanoFramework.DependencyInjection.UnitTests.Fakes
{
public class FakeObject : IFakeObject
Expand Down
2 changes: 0 additions & 2 deletions tests/Fakes/IRootService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
// See LICENSE file in the project root for full license information.
//

using System;

namespace nanoFramework.DependencyInjection.UnitTests.Fakes
{
internal interface IRootService
Expand Down
2 changes: 0 additions & 2 deletions tests/Fakes/IService1.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
// See LICENSE file in the project root for full license information.
//

using System;

namespace nanoFramework.DependencyInjection.UnitTests.Fakes
{
internal interface IService1
Expand Down
2 changes: 0 additions & 2 deletions tests/Fakes/IService2.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
// See LICENSE file in the project root for full license information.
//

using System;

namespace nanoFramework.DependencyInjection.UnitTests.Fakes
{
internal interface IService2
Expand Down
Loading

0 comments on commit a09fbd7

Please sign in to comment.