Skip to content

Commit 6dd92df

Browse files
spasartoENikS
authored andcommitted
Translated error messages to english per issue 19. (#27)
Added resolution customization.
1 parent 714eb9e commit 6dd92df

7 files changed

+144
-56
lines changed

src/HostingExtension.cs

+11-7
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,32 @@
11
using Microsoft.AspNetCore.Hosting;
22
using Microsoft.Extensions.DependencyInjection;
33
using Microsoft.Extensions.DependencyInjection.Extensions;
4+
using System;
45

56
namespace Unity.Microsoft.DependencyInjection
67
{
78
public static class HostingExtension
89
{
9-
private static ServiceProviderFactory _factory;
10-
1110
public static IWebHostBuilder UseUnityServiceProvider(this IWebHostBuilder hostBuilder, IUnityContainer container = null)
1211
{
13-
_factory = new ServiceProviderFactory(container);
12+
return UseUnityServiceProvider(hostBuilder, c => c.UnityContainer = container);
13+
}
14+
15+
public static IWebHostBuilder UseUnityServiceProvider(this IWebHostBuilder hostBuilder, Action<UnityConfigurationOptions> config)
16+
{
17+
var factory = new ServiceProviderFactory(config);
1418

1519
#if NETCOREAPP1_1
1620
return hostBuilder.ConfigureServices((services) =>
1721
{
18-
services.Replace(ServiceDescriptor.Singleton<IServiceProviderFactory<IUnityContainer>>(_factory));
19-
services.Replace(ServiceDescriptor.Singleton<IServiceProviderFactory<IServiceCollection>>(_factory));
22+
services.Replace(ServiceDescriptor.Singleton<IServiceProviderFactory<IUnityContainer>>(factory));
23+
services.Replace(ServiceDescriptor.Singleton<IServiceProviderFactory<IServiceCollection>>(factory));
2024
});
2125
#else
2226
return hostBuilder.ConfigureServices((context, services) =>
2327
{
24-
services.Replace(ServiceDescriptor.Singleton<IServiceProviderFactory<IUnityContainer>>(_factory));
25-
services.Replace(ServiceDescriptor.Singleton<IServiceProviderFactory<IServiceCollection>>(_factory));
28+
services.Replace(ServiceDescriptor.Singleton<IServiceProviderFactory<IUnityContainer>>(factory));
29+
services.Replace(ServiceDescriptor.Singleton<IServiceProviderFactory<IServiceCollection>>(factory));
2630
});
2731
#endif
2832
}

src/Policy/ConstructorSelectorPolicy.cs

+3-5
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,7 @@ private ConstructorInfo FindDependencyConstructor<T>(IBuilderContext context)
4848
case 1: return injectionConstructors[0];
4949
default:
5050
throw new InvalidOperationException(
51-
$"Existem multiplos construtores decorados com Inject para a classe " +
52-
$"{context.BuildKey.Type.GetTypeInfo().Name}");
51+
$"There are multiple constructors decorated with Inject attribute for the class {context.BuildKey.Type.GetTypeInfo().Name}");
5352
}
5453
}
5554

@@ -115,8 +114,7 @@ private ConstructorInfo Other(ConstructorInfo[] constructors, IBuilderContext co
115114
&& !parameters.All(p => p.ParameterType.GetTypeInfo().IsInterface))
116115
return bestConstructor;
117116

118-
var msg = $"Falha ao procurar um construtor para {context.BuildKey.Type.FullName}\n" +
119-
$"Há uma abiquidade entre os construtores";
117+
var msg = $"Failed to search for a constructor for {context.BuildKey.Type.FullName}{Environment.NewLine}There is an abnormality between the constructors";
120118
throw new InvalidOperationException(msg);
121119
}
122120
else
@@ -131,7 +129,7 @@ private ConstructorInfo Other(ConstructorInfo[] constructors, IBuilderContext co
131129
{
132130
//return null;
133131
throw new InvalidOperationException(
134-
$"Construtor não encontrado para {context.BuildKey.Type.FullName}");
132+
$"Constructor not found for {context.BuildKey.Type.FullName}");
135133
}
136134
else
137135
{

src/ServiceProvider.cs

+34-20
Original file line numberDiff line numberDiff line change
@@ -4,31 +4,37 @@
44

55
namespace Unity.Microsoft.DependencyInjection
66
{
7-
public class ServiceProvider : IServiceProvider,
8-
IServiceScopeFactory,
9-
IServiceScope,
7+
public class ServiceProvider : IServiceProvider,
8+
IServiceScopeFactory,
9+
IServiceScope,
1010
IDisposable
1111
{
12-
private IUnityContainer _container;
12+
private readonly UnityConfigurationOptions _options;
1313

14-
15-
internal ServiceProvider(IUnityContainer container)
14+
internal ServiceProvider(UnityConfigurationOptions options)
1615
{
17-
_container = container;
18-
_container.RegisterInstance<IServiceScope>(this, new ExternallyControlledLifetimeManager());
19-
_container.RegisterInstance<IServiceProvider>(this, new ExternallyControlledLifetimeManager());
20-
_container.RegisterInstance<IServiceScopeFactory>(this, new ExternallyControlledLifetimeManager());
16+
_options = options;
17+
_options.UnityContainer.RegisterInstance<IServiceScope>(this, new ExternallyControlledLifetimeManager());
18+
_options.UnityContainer.RegisterInstance<IServiceProvider>(this, new ExternallyControlledLifetimeManager());
19+
_options.UnityContainer.RegisterInstance<IServiceScopeFactory>(this, new ExternallyControlledLifetimeManager());
2120
}
2221

2322
#region IServiceProvider
2423

2524
public object GetService(Type serviceType)
2625
{
26+
ResolutionParameters parameters = new ResolutionParameters { Type = serviceType };
27+
28+
_options.ResolveConfiguration?.Invoke(parameters);
29+
2730
try
2831
{
29-
return _container.Resolve(serviceType);
32+
return _options.UnityContainer.Resolve(parameters.Type, parameters.Name, parameters.ResolverOverrides ?? Array.Empty<Resolution.ResolverOverride>());
33+
}
34+
catch
35+
{
36+
parameters.ResolutionFailureHanlder?.Invoke(serviceType);
3037
}
31-
catch { /* Ignore */}
3238

3339
return null;
3440
}
@@ -40,7 +46,10 @@ public object GetService(Type serviceType)
4046

4147
public IServiceScope CreateScope()
4248
{
43-
return new ServiceProvider(_container.CreateChildContainer());
49+
var childOptions = _options.With(_options.UnityContainer.CreateChildContainer());
50+
childOptions.CreateScope?.Invoke(childOptions);
51+
52+
return new ServiceProvider(childOptions);
4453
}
4554

4655
#endregion
@@ -57,13 +66,15 @@ public IServiceScope CreateScope()
5766

5867
public static IServiceProvider ConfigureServices(IServiceCollection services)
5968
{
60-
return new ServiceProvider(new UnityContainer().AddExtension(new MdiExtension())
61-
.AddServices(services));
69+
var container = new UnityContainer().AddExtension(new MdiExtension())
70+
.AddServices(services);
71+
72+
return new ServiceProvider(new UnityConfigurationOptions { UnityContainer = container });
6273
}
6374

6475
public static explicit operator UnityContainer(ServiceProvider c)
6576
{
66-
return (UnityContainer)c._container;
77+
return (UnityContainer)c._options.UnityContainer;
6778
}
6879

6980
#endregion
@@ -77,11 +88,14 @@ public void Dispose()
7788
GC.SuppressFinalize(this);
7889
}
7990

80-
private void Dispose(bool _)
91+
protected virtual void Dispose(bool _)
92+
{
93+
_options.UnityContainer?.Dispose();
94+
}
95+
96+
~ServiceProvider()
8197
{
82-
IDisposable disposable = _container;
83-
_container = null;
84-
disposable?.Dispose();
98+
Dispose(false);
8599
}
86100

87101
#endregion

src/ServiceProviderExtensions.cs

+12-6
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,10 @@ public static class ServiceProviderExtensions
1717
/// <returns>The <see cref="ServiceProvider"/>.</returns>
1818
public static IServiceProvider BuildServiceProvider(this IServiceCollection services, bool validateScopes = false)
1919
{
20-
return new ServiceProvider(new UnityContainer().AddExtension(new MdiExtension())
21-
.AddServices(services));
20+
var container = new UnityContainer().AddExtension(new MdiExtension())
21+
.AddServices(services);
22+
23+
return new ServiceProvider(new UnityConfigurationOptions { UnityContainer = container });
2224
}
2325

2426
/// <summary>
@@ -30,8 +32,10 @@ public static IServiceProvider BuildServiceProvider(this IServiceCollection serv
3032
/// <returns>Service provider</returns>
3133
public static IServiceProvider BuildServiceProvider(this IServiceCollection services, IUnityContainer container)
3234
{
33-
return new ServiceProvider(container.AddExtension(new MdiExtension())
34-
.AddServices(services));
35+
container.AddExtension(new MdiExtension())
36+
.AddServices(services);
37+
38+
return new ServiceProvider(new UnityConfigurationOptions { UnityContainer = container });
3539
}
3640

3741
/// <summary>
@@ -43,8 +47,10 @@ public static IServiceProvider BuildServiceProvider(this IServiceCollection serv
4347
/// <returns>Service provider</returns>
4448
public static IServiceProvider BuildServiceProvider(this IUnityContainer container, IServiceCollection services)
4549
{
46-
return new ServiceProvider(container.AddExtension(new MdiExtension())
47-
.AddServices(services));
50+
container.AddExtension(new MdiExtension())
51+
.AddServices(services);
52+
53+
return new ServiceProvider(new UnityConfigurationOptions { UnityContainer = container });
4854
}
4955
}
5056
}

src/ServiceProviderFactory.cs

+26-15
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,22 @@
1-
using System;
2-
using Microsoft.Extensions.DependencyInjection;
1+
using Microsoft.Extensions.DependencyInjection;
2+
using System;
33
using Unity.Lifetime;
44

55
namespace Unity.Microsoft.DependencyInjection
66
{
77
public class ServiceProviderFactory : IServiceProviderFactory<IUnityContainer>,
88
IServiceProviderFactory<IServiceCollection>
99
{
10-
private readonly IUnityContainer _container;
10+
private readonly Action<UnityConfigurationOptions> _config;
1111

12-
public ServiceProviderFactory(IUnityContainer container)
12+
public ServiceProviderFactory(Action<UnityConfigurationOptions> config)
1313
{
14-
_container = container ?? new UnityContainer();
15-
16-
_container.RegisterInstance<IServiceProviderFactory<IUnityContainer>>(this, new ContainerControlledLifetimeManager());
17-
_container.RegisterInstance<IServiceProviderFactory<IServiceCollection>>(this, new ExternallyControlledLifetimeManager());
14+
_config = config;
1815
}
1916

2017
public IServiceProvider CreateServiceProvider(IUnityContainer container)
2118
{
22-
return new ServiceProvider(container);
19+
return new ServiceProvider(CreateOptions().With(container));
2320
}
2421

2522
public IServiceProvider CreateServiceProvider(IServiceCollection containerBuilder)
@@ -29,22 +26,36 @@ public IServiceProvider CreateServiceProvider(IServiceCollection containerBuilde
2926

3027
IUnityContainer IServiceProviderFactory<IUnityContainer>.CreateBuilder(IServiceCollection services)
3128
{
32-
return CreateServiceProviderContainer(services);
29+
return CreateServiceProviderContainer(services).UnityContainer;
3330
}
3431

3532
IServiceCollection IServiceProviderFactory<IServiceCollection>.CreateBuilder(IServiceCollection services)
3633
{
3734
return services;
3835
}
3936

37+
private UnityConfigurationOptions CreateServiceProviderContainer(IServiceCollection services)
38+
{
39+
var options = CreateOptions();
40+
options.UnityContainer.AddServices(services);
41+
return options;
42+
}
4043

41-
private IUnityContainer CreateServiceProviderContainer(IServiceCollection services)
44+
private UnityConfigurationOptions CreateOptions()
4245
{
43-
var container = _container.CreateChildContainer();
44-
new ServiceProviderFactory(container);
46+
var options = new UnityConfigurationOptions();
47+
_config(options);
48+
options.UnityContainer = options.UnityContainer ?? new UnityContainer();
49+
ConfigureContainer(options.UnityContainer);
4550

46-
return container.AddExtension(new MdiExtension())
47-
.AddServices(services);
51+
return options;
52+
}
53+
54+
private void ConfigureContainer(IUnityContainer container)
55+
{
56+
container.AddExtension(new MdiExtension());
57+
container.RegisterInstance<IServiceProviderFactory<IUnityContainer>>(this, new ContainerControlledLifetimeManager());
58+
container.RegisterInstance<IServiceProviderFactory<IServiceCollection>>(this, new ExternallyControlledLifetimeManager());
4859
}
4960
}
5061
}

src/Unity.Microsoft.DependencyInjection.csproj

+5-3
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
<Import Project="..\package.props" />
44

55
<PropertyGroup>
6-
<FileVersion>$(Version).0</FileVersion>
7-
<AssemblyVersion>$(Version).0</AssemblyVersion>
6+
<FileVersion>2.1.2.1</FileVersion>
7+
<AssemblyVersion>2.1.2.1</AssemblyVersion>
88
<PackageId>Unity.Microsoft.DependencyInjection</PackageId>
99
<Description>Unity for Microsoft Dependency Injection framework.</Description>
1010
<Copyright>Copyright © Unity Container Project 2018</Copyright>
@@ -19,11 +19,13 @@
1919
<RootNamespace>Unity.Microsoft.DependencyInjection</RootNamespace>
2020
<UnityAbstractions>..\..\Abstractions\src\Unity.Abstractions.csproj</UnityAbstractions>
2121
<UnityContainer>..\..\Container\src\Unity.Container.csproj</UnityContainer>
22+
<Version>2.1.2.1</Version>
23+
<PackageReleaseNotes>Extended to allow for resolution customization. Updated error language to english.</PackageReleaseNotes>
2224
</PropertyGroup>
2325

2426

2527
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
26-
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
28+
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
2729
<TargetFramework>netstandard2.0</TargetFramework>
2830
<DebugType>Full</DebugType>
2931
</PropertyGroup>

src/UnityConfigurationOptions.cs

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
using Unity.Resolution;
5+
6+
namespace Unity.Microsoft.DependencyInjection
7+
{
8+
public class UnityConfigurationOptions
9+
{
10+
/// <summary>
11+
/// The container to use as the root container.
12+
/// </summary>
13+
public IUnityContainer UnityContainer { get; set; }
14+
/// <summary>
15+
/// Controls the unity resolution parameters when resolving a type via the ServiceProvider.
16+
/// </summary>
17+
public Action<ResolutionParameters> ResolveConfiguration { get; set; }
18+
/// <summary>
19+
/// Configures the scope options when a new child scope is created.
20+
/// </summary>
21+
public Action<UnityConfigurationOptions> CreateScope { get; set; }
22+
23+
public UnityConfigurationOptions With(IUnityContainer unityContainer = null, Action<ResolutionParameters> resolutionConfiguration = null, Action<UnityConfigurationOptions> createScope = null)
24+
{
25+
return new UnityConfigurationOptions
26+
{
27+
UnityContainer = unityContainer ?? UnityContainer,
28+
ResolveConfiguration = resolutionConfiguration ?? ResolveConfiguration,
29+
CreateScope = createScope ?? CreateScope
30+
};
31+
}
32+
}
33+
34+
public class ResolutionParameters
35+
{
36+
/// <summary>
37+
/// The type being resolved.
38+
/// </summary>
39+
public Type Type { get; set; }
40+
/// <summary>
41+
/// The name to use when resolving the type.
42+
/// </summary>
43+
public string Name { get; set; }
44+
/// <summary>
45+
/// The resolver overrides to use when resolving the type.
46+
/// </summary>
47+
public ResolverOverride[] ResolverOverrides { get; set; }
48+
/// <summary>
49+
/// Action to call when a type resolution fails.
50+
/// </summary>
51+
public Action<Type> ResolutionFailureHanlder { get; set; }
52+
}
53+
}

0 commit comments

Comments
 (0)