Skip to content

Commit 081c394

Browse files
author
Alessandro Calorì
committed
Ported, fixed and refactored sources from Unity.Mvc official branch.
1 parent f4417c7 commit 081c394

File tree

7 files changed

+396
-0
lines changed

7 files changed

+396
-0
lines changed

package.sln

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio 15
4+
VisualStudioVersion = 15.0.27004.2005
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Unity.DependencyInjection", "src\Unity.DependencyInjection.csproj", "{520251C7-14E6-434F-A26E-67E9762635BD}"
7+
EndProject
8+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Test", "Test", "{DA61FEC3-1E17-4DCF-AC19-A6482A547741}"
9+
EndProject
10+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DependencyInjection.Tests", "tests\DependencyInjection.Tests.csproj", "{FCC3DAA4-9136-4C55-926D-7DBD5BEDE8D8}"
11+
EndProject
12+
Global
13+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
14+
Debug|Any CPU = Debug|Any CPU
15+
Release|Any CPU = Release|Any CPU
16+
EndGlobalSection
17+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
18+
{520251C7-14E6-434F-A26E-67E9762635BD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
19+
{520251C7-14E6-434F-A26E-67E9762635BD}.Debug|Any CPU.Build.0 = Debug|Any CPU
20+
{520251C7-14E6-434F-A26E-67E9762635BD}.Release|Any CPU.ActiveCfg = Release|Any CPU
21+
{520251C7-14E6-434F-A26E-67E9762635BD}.Release|Any CPU.Build.0 = Release|Any CPU
22+
{FCC3DAA4-9136-4C55-926D-7DBD5BEDE8D8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
23+
{FCC3DAA4-9136-4C55-926D-7DBD5BEDE8D8}.Debug|Any CPU.Build.0 = Debug|Any CPU
24+
{FCC3DAA4-9136-4C55-926D-7DBD5BEDE8D8}.Release|Any CPU.ActiveCfg = Release|Any CPU
25+
{FCC3DAA4-9136-4C55-926D-7DBD5BEDE8D8}.Release|Any CPU.Build.0 = Release|Any CPU
26+
EndGlobalSection
27+
GlobalSection(SolutionProperties) = preSolution
28+
HideSolutionNode = FALSE
29+
EndGlobalSection
30+
GlobalSection(NestedProjects) = preSolution
31+
{FCC3DAA4-9136-4C55-926D-7DBD5BEDE8D8} = {DA61FEC3-1E17-4DCF-AC19-A6482A547741}
32+
EndGlobalSection
33+
GlobalSection(ExtensibilityGlobals) = postSolution
34+
SolutionGuid = {F94EF33F-E0A3-449E-8703-D60D4F6F9D0E}
35+
EndGlobalSection
36+
EndGlobal

src/Configuration.cs

Lines changed: 243 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,243 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Reflection;
5+
6+
using Microsoft.Extensions.DependencyInjection;
7+
8+
using Unity.Injection;
9+
using Unity.Lifetime;
10+
11+
namespace Unity.DependencyInjection
12+
{
13+
public static class Configuration
14+
{
15+
public static void Register(IServiceCollection services, IUnityContainer _container)
16+
{
17+
_container.RegisterType<IServiceScopeFactory, ServiceScopeFactory>();
18+
_container.RegisterType<IServiceScope, ServiceScope>();
19+
_container.RegisterType<IServiceProvider, ServiceProvider>();
20+
21+
RegisterEnumerable(_container);
22+
23+
HashSet<Type> aggregateTypes = GetAggregateTypes(services);
24+
25+
MethodInfo registerInstance = RegisterInstance();
26+
27+
Func<ServiceDescriptor, LifetimeManager> lifetime = GetLifetime();
28+
29+
// Configure all registrations into Unity
30+
foreach (ServiceDescriptor serviceDescriptor in services)
31+
{
32+
RegisterType(
33+
_container,
34+
lifetime,
35+
serviceDescriptor,
36+
aggregateTypes,
37+
registerInstance);
38+
}
39+
}
40+
41+
private static MethodInfo RegisterInstance()
42+
{
43+
return
44+
typeof(UnityContainerExtensions)
45+
.GetRuntimeMethods()
46+
.Single(o =>
47+
o.IsStatic &&
48+
o.IsPublic &&
49+
o.IsGenericMethod &&
50+
o.Name == "RegisterInstance" &&
51+
o.GetParameters().Length == 4);
52+
}
53+
54+
private static HashSet<Type> GetAggregateTypes(IServiceCollection services)
55+
{
56+
var aggregateTypes = new HashSet<Type>
57+
(
58+
services.GroupBy
59+
(
60+
serviceDescriptor => serviceDescriptor.ServiceType,
61+
serviceDescriptor => serviceDescriptor
62+
)
63+
.Where(typeGrouping => typeGrouping.Count() > 1)
64+
.Select(type => type.Key)
65+
);
66+
67+
return aggregateTypes;
68+
}
69+
70+
private static void RegisterEnumerable(IUnityContainer _container)
71+
{
72+
_container.RegisterType
73+
(
74+
typeof(IEnumerable<>),
75+
new InjectionFactory
76+
(
77+
(container, enumerableType, name) =>
78+
{
79+
Type type = enumerableType.GenericTypeArguments.Single();
80+
Type genericType = type.GetGenericTypeDefinition();
81+
82+
object[] allInstances = container.ResolveAll(type).Concat
83+
(
84+
_container.IsRegistered(type) ||
85+
type.GenericTypeArguments.Any() &&
86+
_container.IsRegistered(genericType)
87+
? new[] {container.Resolve(type)}
88+
: new object[] { }
89+
)
90+
.ToArray();
91+
92+
return
93+
typeof(Enumerable).GetRuntimeMethod("OfType", new[] {typeof(object[])})
94+
.MakeGenericMethod(type)
95+
.Invoke(null, new object[] {allInstances});
96+
}
97+
)
98+
);
99+
}
100+
101+
private static Func<ServiceDescriptor, LifetimeManager> GetLifetime()
102+
{
103+
return serviceDescriptor =>
104+
{
105+
switch (serviceDescriptor.Lifetime)
106+
{
107+
case ServiceLifetime.Scoped:
108+
return new HierarchicalLifetimeManager();
109+
110+
case ServiceLifetime.Singleton:
111+
return new ContainerControlledLifetimeManager();
112+
113+
case ServiceLifetime.Transient:
114+
return new TransientLifetimeManager();
115+
116+
default:
117+
throw new NotImplementedException($"Unsupported lifetime manager type '{serviceDescriptor.Lifetime}'");
118+
}
119+
};
120+
}
121+
122+
private static void RegisterType(
123+
IUnityContainer _container,
124+
Func<ServiceDescriptor, LifetimeManager> fetchLifetime,
125+
ServiceDescriptor serviceDescriptor,
126+
ICollection<Type> aggregateTypes,
127+
MethodInfo miRegisterInstanceOpen)
128+
{
129+
LifetimeManager lifetimeManager = fetchLifetime(serviceDescriptor);
130+
bool isAggregateType = aggregateTypes.Contains(serviceDescriptor.ServiceType);
131+
132+
if (serviceDescriptor.ImplementationType != null)
133+
{
134+
RegisterImplementation(_container, serviceDescriptor, isAggregateType, lifetimeManager);
135+
}
136+
else if (serviceDescriptor.ImplementationFactory != null)
137+
{
138+
RegisterFactory(_container, serviceDescriptor, isAggregateType, lifetimeManager);
139+
}
140+
else if (serviceDescriptor.ImplementationInstance != null)
141+
{
142+
RegisterSingleton(_container, serviceDescriptor, miRegisterInstanceOpen, isAggregateType, lifetimeManager);
143+
}
144+
else
145+
{
146+
throw new InvalidOperationException("Unsupported registration type");
147+
}
148+
}
149+
150+
private static void RegisterImplementation(
151+
IUnityContainer _container,
152+
ServiceDescriptor serviceDescriptor,
153+
bool isAggregateType,
154+
LifetimeManager lifetimeManager)
155+
{
156+
if (isAggregateType)
157+
{
158+
_container.RegisterType(
159+
serviceDescriptor.ServiceType,
160+
serviceDescriptor.ImplementationType,
161+
serviceDescriptor.ImplementationType.AssemblyQualifiedName,
162+
lifetimeManager);
163+
}
164+
else
165+
{
166+
_container.RegisterType(
167+
serviceDescriptor.ServiceType,
168+
serviceDescriptor.ImplementationType,
169+
lifetimeManager);
170+
}
171+
}
172+
173+
private static void RegisterFactory(
174+
IUnityContainer _container,
175+
ServiceDescriptor serviceDescriptor,
176+
bool isAggregateType,
177+
LifetimeManager lifetimeManager)
178+
{
179+
if (isAggregateType)
180+
{
181+
_container.RegisterType
182+
(
183+
serviceDescriptor.ServiceType,
184+
serviceDescriptor.ImplementationType.AssemblyQualifiedName,
185+
lifetimeManager,
186+
new InjectionFactory
187+
(
188+
container =>
189+
{
190+
var serviceProvider = container.Resolve<IServiceProvider>();
191+
object instance = serviceDescriptor.ImplementationFactory(serviceProvider);
192+
return instance;
193+
}
194+
)
195+
);
196+
}
197+
else
198+
{
199+
_container.RegisterType
200+
(
201+
serviceDescriptor.ServiceType,
202+
lifetimeManager,
203+
new InjectionFactory
204+
(
205+
container =>
206+
{
207+
var serviceProvider = container.Resolve<IServiceProvider>();
208+
object instance = serviceDescriptor.ImplementationFactory(serviceProvider);
209+
return instance;
210+
}
211+
)
212+
);
213+
}
214+
}
215+
216+
private static void RegisterSingleton(
217+
IUnityContainer _container,
218+
ServiceDescriptor serviceDescriptor,
219+
MethodInfo miRegisterInstanceOpen,
220+
bool isAggregateType,
221+
LifetimeManager lifetimeManager)
222+
{
223+
if (isAggregateType)
224+
{
225+
miRegisterInstanceOpen
226+
.MakeGenericMethod(serviceDescriptor.ServiceType)
227+
.Invoke(null,
228+
new[]
229+
{
230+
_container, serviceDescriptor.ImplementationType.AssemblyQualifiedName,
231+
serviceDescriptor.ImplementationInstance, lifetimeManager
232+
});
233+
}
234+
else
235+
{
236+
_container.RegisterInstance(
237+
serviceDescriptor.ServiceType,
238+
serviceDescriptor.ImplementationInstance,
239+
lifetimeManager);
240+
}
241+
}
242+
}
243+
}

src/ServiceProvider.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
using System;
2+
3+
namespace Unity.DependencyInjection
4+
{
5+
public class ServiceProvider : IServiceProvider
6+
{
7+
private readonly IUnityContainer container;
8+
9+
public ServiceProvider(IUnityContainer container)
10+
{
11+
this.container = container;
12+
}
13+
14+
public object GetService(Type serviceType)
15+
{
16+
return container.Resolve(serviceType);
17+
}
18+
}
19+
}

src/ServiceScope.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
using System;
2+
3+
using Microsoft.Extensions.DependencyInjection;
4+
5+
namespace Unity.DependencyInjection
6+
{
7+
public class ServiceScope : IServiceScope
8+
{
9+
private readonly IUnityContainer container;
10+
11+
public ServiceScope(IUnityContainer container)
12+
{
13+
this.container = container.CreateChildContainer();
14+
}
15+
16+
public IServiceProvider ServiceProvider =>
17+
container.Resolve<IServiceProvider>();
18+
19+
public void Dispose()
20+
{
21+
container.Dispose();
22+
}
23+
}
24+
}

src/ServiceScopeFactory.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
using Microsoft.Extensions.DependencyInjection;
2+
3+
namespace Unity.DependencyInjection
4+
{
5+
public class ServiceScopeFactory : IServiceScopeFactory
6+
{
7+
private readonly IUnityContainer container;
8+
9+
public ServiceScopeFactory(IUnityContainer container)
10+
{
11+
this.container = container;
12+
}
13+
14+
public IServiceScope CreateScope()
15+
{
16+
return container.Resolve<IServiceScope>();
17+
}
18+
}
19+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<Version>1.0.0</Version>
5+
<AssemblyVersion>1.0.0.0</AssemblyVersion>
6+
<FileVersion>1.0.0.0</FileVersion>
7+
<PackageId>Unity.DependencyInjection</PackageId>
8+
<Description>Unity for Microsoft Dependency Injection framework.</Description>
9+
<Copyright>Copyright © Microsoft.Practices.Unity 2017</Copyright>
10+
<PackageProjectUrl>https://github.com/unitycontainer</PackageProjectUrl>
11+
<RepositoryUrl>https://github.com/unitycontainer/microsoft-dependency-injection</RepositoryUrl>
12+
<PackageLicenseUrl>https://github.com/unitycontainer/microsoft-dependency-injection/blob/master/LICENSE</PackageLicenseUrl>
13+
<PackageIconUrl>https://avatars1.githubusercontent.com/u/12849707</PackageIconUrl>
14+
<RepositoryType>git</RepositoryType>
15+
<PackageReleaseNotes>This package is distributed as .NET Standard 1.0 and .NET Framework 4.7 package.</PackageReleaseNotes>
16+
<Authors>Microsoft.Practices.Unity</Authors>
17+
<Company>Microsoft.Practices.Unity</Company>
18+
<RootNamespace>Unity.DependencyInjection</RootNamespace>
19+
</PropertyGroup>
20+
21+
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
22+
<TargetFrameworks>netstandard1.0;net47</TargetFrameworks>
23+
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
24+
</PropertyGroup>
25+
26+
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
27+
<TargetFramework>netstandard1.0</TargetFramework>
28+
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
29+
<DebugType>Full</DebugType>
30+
</PropertyGroup>
31+
32+
<ItemGroup>
33+
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="1.1.1" />
34+
<PackageReference Include="Unity" Version="5.0.2" />
35+
</ItemGroup>
36+
37+
</Project>

0 commit comments

Comments
 (0)