Microsoft.Framework.DependencyInjection.Ninject
该工程内部共包含5个类文件,底层使用Ninject实现依赖注入,工程截图如下:
从文件命名可以看出,NinjectServiceProvider和NinjectServiceScopeFactory分别是接口IServiceProvider和IServiceScopeFactory的实现类。
(IServiceScope接口的实现类作为NinjectServiceScopeFactory内部类而存在,没有作为单独的文件。)
而工程的入口依旧是Registration为结尾的NinjectRegistration类。
NinjectRegistration
文件代码如下
public static class NinjectRegistration { public static void Populate(this IKernel kernel, IEnumerable<ServiceDescriptor> descriptors) { kernel.Load(new ServiceProviderNinjectModule(descriptors)); } public static IBindingNamedWithOrOnSyntax<T> InRequestScope<T>( this IBindingWhenInNamedWithOrOnSyntax<T> binding) { return binding.InScope(context => context.Parameters.GetScopeParameter()); } internal static ScopeParameter GetScopeParameter(this IEnumerable<IParameter> parameters) { return (ScopeParameter)(parameters .Where(p => p.Name == typeof(ScopeParameter).FullName) .SingleOrDefault()); } internal static IEnumerable<IParameter> AddOrReplaceScopeParameter( this IEnumerable<IParameter> parameters, ScopeParameter scopeParameter) { return parameters .Where(p => p.Name != typeof(ScopeParameter).FullName) .Concat(new[] { scopeParameter }); } }
静态方法:
Populate:作用是将ServiceProviderNinjectModule注册到内核中。对于Ninject大多数时候都会将自定义继承自NinjectModule的类注册到内核中,并且使用该继承类管理依赖注入。
GetScopeParameter:获取所有“ScopeParameter”类型的参数
AddOrReplaceScopeParameter:获取所有“ScopeParameter”参数,并且将它替换成传入的“scopeParameter”。
InRequestScope:在“binding.InScope”中添加“ScopeParameter”。
总体说来,该文件都是些辅助方法,也是对外初始化的接口。
ServiceProviderNinjectModule
文件代码如下:
internal class ServiceProviderNinjectModule : NinjectModule { private readonly IEnumerable<ServiceDescriptor> _serviceDescriptors; public ServiceProviderNinjectModule( IEnumerable<ServiceDescriptor> serviceDescriptors) { _serviceDescriptors = serviceDescriptors; } public override void Load() { foreach (var descriptor in _serviceDescriptors) { IBindingWhenInNamedWithOrOnSyntax<object> binding; if (descriptor.ImplementationType != null) { binding = Bind(descriptor.ServiceType).To(descriptor.ImplementationType); } else if (descriptor.ImplementationFactory != null) { binding = Bind(descriptor.ServiceType).ToMethod(context => { var serviceProvider = context.Kernel.Get<IServiceProvider>(); return descriptor.ImplementationFactory(serviceProvider); }); } else { binding = Bind(descriptor.ServiceType).ToConstant(descriptor.ImplementationInstance); } switch (descriptor.Lifetime) { case ServiceLifetime.Singleton: binding.InSingletonScope(); break; case ServiceLifetime.Scoped: binding.InRequestScope(); break; case ServiceLifetime.Transient: binding.InTransientScope(); break; } } Bind<IServiceProvider>().ToMethod(context => { var resolver = context.Kernel.Get<IResolutionRoot>(); var inheritedParams = context.Parameters.Where(p => p.ShouldInherit); var scopeParam = new ScopeParameter(); inheritedParams = inheritedParams.AddOrReplaceScopeParameter(scopeParam); return new NinjectServiceProvider(resolver, inheritedParams.ToArray()); }).InRequestScope(); Bind<IServiceScopeFactory>().ToMethod(context => { return new NinjectServiceScopeFactory(context); }).InRequestScope(); } }