Skip to content

Commit 0dc4bcf

Browse files
committed
Add Kooboo.Common.ObjectContainer.Ninject
1 parent 5f68332 commit 0dc4bcf

16 files changed

+919
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,272 @@
1+
#region License
2+
//
3+
// Copyright (c) 2013, Kooboo team
4+
//
5+
// Licensed under the BSD License
6+
// See the file LICENSE.txt for details.
7+
//
8+
#endregion
9+
using System;
10+
using System.Collections.Generic;
11+
using System.Linq;
12+
using System.Web;
13+
using Ninject;
14+
using Ninject.Syntax;
15+
using NinjectParameters = Ninject.Parameters;
16+
using Kooboo.Common.ObjectContainer.Ninject.InRequestScope;
17+
using Kooboo.Common.ObjectContainer.Dependency;
18+
namespace Kooboo.Common.ObjectContainer.Ninject
19+
{
20+
/// <summary>
21+
/// 加入Container Manager是为了减少其它程序在做注入的时候减少对Ninject的依赖
22+
/// 有了这个类以后,未来的扩展程序集在注册组件时就不用引用Ninject,对它形成依赖。
23+
/// </summary>
24+
public class ContainerManager : IContainerManager
25+
{
26+
private class KernelWrapper : StandardKernel
27+
{
28+
29+
#region AddResolvingObserver
30+
private IList<IResolvingObserver> _resolvingObjservers = new List<IResolvingObserver>();
31+
public void AddResolvingObserver(IResolvingObserver observer)
32+
{
33+
_resolvingObjservers.Add(observer);
34+
_resolvingObjservers = _resolvingObjservers.OrderBy(it => it.Order).ToList();
35+
}
36+
37+
private object OnResolved(object resolvedObject)
38+
{
39+
if (_resolvingObjservers.Count > 0)
40+
{
41+
foreach (var item in _resolvingObjservers)
42+
{
43+
resolvedObject = item.OnResolved(resolvedObject);
44+
}
45+
}
46+
return resolvedObject;
47+
}
48+
#endregion
49+
public override IEnumerable<object> Resolve(global::Ninject.Activation.IRequest request)
50+
{
51+
return base.Resolve(request).Select(it => OnResolved(it));
52+
}
53+
}
54+
55+
#region .ctor
56+
private KernelWrapper _container;
57+
58+
public ContainerManager()
59+
{
60+
_container = new KernelWrapper();
61+
62+
_container.Settings.Set("InjectAttribute", typeof(Kooboo.Common.ObjectContainer.Dependency.InjectAttribute));
63+
}
64+
65+
/// <summary>
66+
/// Ninject
67+
/// </summary>
68+
public IKernel Container
69+
{
70+
get { return _container; }
71+
}
72+
#endregion
73+
74+
#region AddComponent
75+
76+
/// <summary>
77+
/// Adds the component.
78+
/// </summary>
79+
/// <typeparam name="TService">The type of the service.</typeparam>
80+
/// <param name="key">The key.</param>
81+
/// <param name="lifeStyle">The life style.</param>
82+
public virtual void AddComponent<TService>(string key = "", ComponentLifeStyle lifeStyle = ComponentLifeStyle.Transient)
83+
{
84+
AddComponent<TService, TService>(key, lifeStyle);
85+
}
86+
87+
/// <summary>
88+
/// Adds the component.
89+
/// </summary>
90+
/// <param name="service">The service.</param>
91+
/// <param name="key">The key.</param>
92+
/// <param name="lifeStyle">The life style.</param>
93+
public virtual void AddComponent(Type service, string key = "", ComponentLifeStyle lifeStyle = ComponentLifeStyle.Transient)
94+
{
95+
AddComponent(service, service, key, lifeStyle);
96+
}
97+
98+
/// <summary>
99+
/// Adds the component.
100+
/// </summary>
101+
/// <typeparam name="TService">The type of the service.</typeparam>
102+
/// <typeparam name="TImplementation">The type of the implementation.</typeparam>
103+
/// <param name="key">The key.</param>
104+
/// <param name="lifeStyle">The life style.</param>
105+
public virtual void AddComponent<TService, TImplementation>(string key = "", ComponentLifeStyle lifeStyle = ComponentLifeStyle.Transient)
106+
{
107+
AddComponent(typeof(TService), typeof(TImplementation), key, lifeStyle);
108+
}
109+
110+
public virtual void AddComponent(Type service, Type implementation, string key = "", ComponentLifeStyle lifeStyle = ComponentLifeStyle.Transient, params Parameter[] parameters)
111+
{
112+
var binding = _container.Bind(service).To(implementation);
113+
if (parameters != null)
114+
{
115+
var ninjectParamters = ConvertParameters(parameters);
116+
foreach (var parameter in ninjectParamters)
117+
{
118+
binding.WithParameter(parameter);
119+
}
120+
}
121+
binding.PerLifeStyle(lifeStyle).MapKey(key).ReplaceExisting(service);
122+
}
123+
124+
public virtual void AddComponentInstance<TService>(object instance, string key = "")
125+
{
126+
AddComponentInstance(typeof(TService), instance, key);
127+
}
128+
public virtual void AddComponentInstance(object instance, string key = "")
129+
{
130+
AddComponentInstance(instance.GetType(), instance, key);
131+
}
132+
public virtual void AddComponentInstance(Type service, object instance, string key = "")
133+
{
134+
_container.Bind(service).ToConstant(instance).MapKey(key).ReplaceExisting(service);
135+
}
136+
#endregion
137+
138+
#region ConvertParameters
139+
private static NinjectParameters.IParameter[] ConvertParameters(Parameter[] parameters)
140+
{
141+
if (parameters == null)
142+
{
143+
return null;
144+
}
145+
return parameters.Select(it => new NinjectParameters.ConstructorArgument(it.Name, (context) => it.ValueCallback())).ToArray();
146+
}
147+
#endregion
148+
#region Resolve
149+
public virtual T Resolve<T>(string key = "", params Parameter[] parameters) where T : class
150+
{
151+
if (string.IsNullOrEmpty(key))
152+
{
153+
return _container.Get<T>(ConvertParameters(parameters));
154+
}
155+
return _container.Get<T>(key, ConvertParameters(parameters));
156+
}
157+
158+
public virtual object Resolve(Type type, string key = "", params Parameter[] parameters)
159+
{
160+
if (string.IsNullOrEmpty(key))
161+
{
162+
return _container.Get(type, ConvertParameters(parameters));
163+
}
164+
return _container.Get(type, key, ConvertParameters(parameters));
165+
}
166+
#endregion
167+
168+
#region ResolveAll
169+
public virtual T[] ResolveAll<T>(string key = "")
170+
{
171+
if (string.IsNullOrEmpty(key))
172+
{
173+
return _container.GetAll<T>().ToArray();
174+
}
175+
return _container.GetAll<T>(key).ToArray();
176+
}
177+
public virtual object[] ResolveAll(Type type, string key = "")
178+
{
179+
if (string.IsNullOrEmpty(key))
180+
{
181+
return _container.GetAll(type).ToArray();
182+
}
183+
return _container.GetAll(type, key).ToArray();
184+
}
185+
#endregion
186+
187+
#region TryResolve
188+
public virtual T TryResolve<T>(string key = "", params Parameter[] parameters)
189+
{
190+
if (string.IsNullOrEmpty(key))
191+
{
192+
return _container.TryGet<T>(ConvertParameters(parameters));
193+
}
194+
return _container.TryGet<T>(key, ConvertParameters(parameters));
195+
}
196+
197+
public virtual object TryResolve(Type type, string key = "", params Parameter[] parameters)
198+
{
199+
if (string.IsNullOrEmpty(key))
200+
{
201+
return _container.TryGet(type, ConvertParameters(parameters));
202+
}
203+
return _container.TryGet(type, key, ConvertParameters(parameters));
204+
}
205+
206+
#endregion
207+
208+
#region ResolveUnregistered
209+
public virtual T ResolveUnregistered<T>() where T : class
210+
{
211+
return ResolveUnregistered(typeof(T)) as T;
212+
}
213+
214+
public virtual object ResolveUnregistered(Type type)
215+
{
216+
var constructors = type.GetConstructors();
217+
foreach (var constructor in constructors)
218+
{
219+
220+
var parameters = constructor.GetParameters();
221+
var parameterInstances = new List<object>();
222+
foreach (var parameter in parameters)
223+
{
224+
var service = Resolve(parameter.ParameterType);
225+
if (service == null)
226+
parameterInstances.Add(service);
227+
}
228+
return Activator.CreateInstance(type, parameterInstances.ToArray());
229+
230+
231+
}
232+
throw new Exception("No contructor was found that had all the dependencies satisfied.");
233+
}
234+
#endregion
235+
236+
#region Dispose
237+
public void Dispose()
238+
{
239+
if (this._container != null && !this._container.IsDisposed)
240+
{
241+
this._container.Dispose();
242+
}
243+
244+
this._container = null;
245+
}
246+
#endregion
247+
248+
#region AddResolvingObserver
249+
public void AddResolvingObserver(IResolvingObserver observer)
250+
{
251+
_container.AddResolvingObserver(observer);
252+
}
253+
#endregion
254+
255+
256+
#region InjectProperties
257+
public void InjectProperties(object instance)
258+
{
259+
this._container.Inject(instance);
260+
}
261+
#endregion
262+
263+
264+
#region ResolveGeneric
265+
public object ResolveGeneric(Type genericType, params Type[] genericTypeParameters)
266+
{
267+
throw new NotImplementedException();
268+
}
269+
#endregion
270+
}
271+
272+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
#region License
2+
//
3+
// Copyright (c) 2013, Kooboo team
4+
//
5+
// Licensed under the BSD License
6+
// See the file LICENSE.txt for details.
7+
//
8+
#endregion
9+
using Ninject.Syntax;
10+
using Ninject.Planning.Bindings;
11+
using System;
12+
using System.Collections.Generic;
13+
using System.Linq;
14+
using System.Text;
15+
using Kooboo.Common.ObjectContainer.Ninject.InRequestScope;
16+
using Kooboo.Common.ObjectContainer.Dependency;
17+
18+
namespace Kooboo.Common.ObjectContainer.Ninject
19+
{
20+
public static class ContainerManagerExtensions
21+
{
22+
public static IBindingNamedWithOrOnSyntax<T> PerLifeStyle<T>(this IBindingWhenInNamedWithOrOnSyntax<T> binding, ComponentLifeStyle lifeStyle)
23+
{
24+
switch (lifeStyle)
25+
{
26+
case ComponentLifeStyle.Singleton:
27+
return binding.InSingletonScope();
28+
case ComponentLifeStyle.InThreadScope:
29+
return binding.InThreadScope();
30+
case ComponentLifeStyle.InRequestScope:
31+
return binding.InRequestScope();
32+
case ComponentLifeStyle.Transient:
33+
default:
34+
return binding.InTransientScope();
35+
}
36+
}
37+
public static IBindingSyntax MapKey<T>(this IBindingNamedSyntax<T> binding, string key)
38+
{
39+
IBindingSyntax bindingSyntax = binding;
40+
if (!string.IsNullOrEmpty(key))
41+
{
42+
bindingSyntax = binding.Named(key);
43+
}
44+
45+
return bindingSyntax;
46+
}
47+
public static void ReplaceExisting(this IBindingSyntax bindingInSyntax, Type type)
48+
{
49+
var kernel = bindingInSyntax.Kernel;
50+
var bindingsToRemove = kernel.GetBindings(type).Where(b => string.Equals(b.Metadata.Name, bindingInSyntax.BindingConfiguration.Metadata.Name, StringComparison.Ordinal));
51+
foreach (var bindingToRemove in bindingsToRemove)
52+
{
53+
kernel.RemoveBinding(bindingToRemove);
54+
}
55+
56+
var binding = new Binding(type, bindingInSyntax.BindingConfiguration);
57+
kernel.AddBinding(binding);
58+
}
59+
}
60+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
#region License
2+
//
3+
// Copyright (c) 2013, Kooboo team
4+
//
5+
// Licensed under the BSD License
6+
// See the file LICENSE.txt for details.
7+
//
8+
#endregion
9+
using System;
10+
using System.Collections.Generic;
11+
using System.Linq;
12+
using Ninject;
13+
using Ninject.Syntax;
14+
using Kooboo.Common.ObjectContainer.Dependency;
15+
namespace Kooboo.Common.ObjectContainer.Ninject
16+
{
17+
/// <summary>
18+
/// Registers service in the inversion of container upon start.
19+
/// </summary>
20+
public class DependencyAttributeRegistrator
21+
{
22+
private readonly ITypeFinder _finder;
23+
private readonly IContainerManager _containerManager;
24+
25+
public DependencyAttributeRegistrator(ITypeFinder finder, IContainerManager containerManager)
26+
{
27+
this._finder = finder;
28+
this._containerManager = containerManager;
29+
}
30+
31+
public virtual IEnumerable<AttributeInfo<DependencyAttribute>> FindServices()
32+
{
33+
foreach (Type type in _finder.FindClassesOfType<object>())
34+
{
35+
var attributes = type.GetCustomAttributes(typeof(DependencyAttribute), false);
36+
foreach (DependencyAttribute attribute in attributes)
37+
{
38+
yield return new AttributeInfo<DependencyAttribute> { Attribute = attribute, DecoratedType = type };
39+
}
40+
}
41+
}
42+
43+
public virtual void RegisterServices()
44+
{
45+
this.RegisterServices(this.FindServices());
46+
}
47+
public virtual void RegisterServices(IEnumerable<AttributeInfo<DependencyAttribute>> services)
48+
{
49+
services = services.OrderBy(it => it.Attribute.Order);
50+
foreach (var info in services)
51+
{
52+
Type serviceType = info.Attribute.ServiceType ?? info.DecoratedType;
53+
_containerManager.AddComponent(serviceType, info.DecoratedType, info.Attribute.Key, info.Attribute.LifeStyle);
54+
}
55+
}
56+
57+
public virtual IEnumerable<AttributeInfo<DependencyAttribute>> FilterServices(IEnumerable<AttributeInfo<DependencyAttribute>> services, params string[] configurationKeys)
58+
{
59+
return services.Where(s => s.Attribute.Configuration == null || configurationKeys.Contains(s.Attribute.Configuration));
60+
}
61+
}
62+
}

0 commit comments

Comments
 (0)