. , , , NHibernate. , Ninject internal IOC .
, Ninject ISelector , . , ( , ). SelectConstructorsForInjection().
public class HydratingSelector : DisposableObject, ISelector
{
private readonly ISelector standardSelector;
private const BindingFlags Flags = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance;
public HydratingSelector(IConstructorScorer constructorScorer,
IEnumerable<IInjectionHeuristic> injectionHeuristics)
{
standardSelector = new Selector(constructorScorer, injectionHeuristics);
}
public IEnumerable<ConstructorInfo> SelectConstructorsForInjection(Type type)
{
if(Settings.GetHydratedTypeSelector()(type))
{
var constructors = type.GetConstructors(Flags);
return constructors.Length != 0 ? constructors : null;
}
return standardSelector.SelectConstructorsForInjection(type);
}
}
, InjectNonPublic = true . InjectAttribute . , HydratingConstructorScorer :
public class HydratingConstructorScorer: DisposableObject, IConstructorScorer
{
private readonly IConstructorScorer standardScorer = new StandardConstructorScorer();
public int Score(IContext context, ConstructorInjectionDirective directive)
{
if(Settings.GetHydratedTypeSelector()(directive.Constructor.DeclaringType)
&& directive.Constructor.HasAttribute(Settings.GetHydrateAttribute()))
return int.MaxValue;
return standardScorer.Score(context, directive);
}
}
, :
public class HydratingKernel : StandardKernel
{
public HydratingKernel(params INinjectModule[] modules)
: base(modules)
{
}
public HydratingKernel(INinjectSettings settings, params INinjectModule[] modules)
: base(settings, modules)
{
}
protected override void AddComponents()
{
base.AddComponents();
SetupComponentsForHydratingKernel(Components);
}
internal static void SetupComponentsForHydratingKernel(IComponentContainer components)
{
components.RemoveAll<ISelector>();
components.Add<ISelector, HydratingSelector>();
components.RemoveAll<IConstructorScorer>();
components.Add<IConstructorScorer, HydratingConstructorScorer>();
}
}