protected virtual bool DoApply(object target, FieldInfo fInfo, IApplicationDependencyInjector injector) { var tf = fInfo.FieldType; //0. Inject application itself if (tf == typeof(IApplication)) { fInfo.SetValue(target, injector.App); return(true); } //1. Inject module if (typeof(IModule).IsAssignableFrom(tf)) { return(TryInjectModule(target, fInfo, injector)); } //2. Try app root objects if (TryInjectAppRootObjects(target, fInfo, injector)) { return(true); } return(false); }
protected override IEnumerable <object> GetApplicationRoots(IApplicationDependencyInjector injector) { foreach (var singleton in injector.App.Singletons) { yield return(singleton); } }
/// <summary> /// Tries to perform module injection by name or type, returning true if assignment was made /// </summary> protected virtual bool TryInjectModule(object target, FieldInfo fInfo, IApplicationDependencyInjector injector) { var needType = Type == null ? fInfo.FieldType : Type; IModule module = null; if (Name.IsNotNullOrWhiteSpace()) { module = injector.App.ModuleRoot.ChildModules[Name]; if (module == null) { return(false); } if (!needType.IsAssignableFrom(module.GetType())) { return(false); //type mismatch } } else { module = injector.App.ModuleRoot.ChildModules .OrderedValues .FirstOrDefault(m => needType.IsAssignableFrom(m.GetType())); if (module == null) { return(false); } } fInfo.SetValue(target, module); return(true); }
/// <summary> /// Override to perform custom dependency injection, the default one loops through the field of non-primitive types and injects on those. /// Return true if the injection handled already by your code and should not continue /// </summary> protected virtual bool DoInjectApplication(IApplicationDependencyInjector injector) { foreach (var fdef in Schema) { if (fdef.NonNullableType.IsValueType) { continue; //no DI on value types } var v = GetFieldValue(fdef); if (v == null) { continue; } if (v is Doc vdoc) //Order of pattern matches is important { injector.App.InjectInto(vdoc); } else if (v is IDictionary vdict) //then DICT as it is also IEnumerable { foreach (var dv in vdict.Values) { if (dv == null) { continue; } if (dv.GetType().IsValueType) { continue; } injector.App.InjectInto(dv); } } else if (v is IEnumerable vedoc) //only then IEnumerable { foreach (var ev in vedoc) { if (ev == null) { continue; } if (ev.GetType().IsValueType) { continue; } injector.App.InjectInto(ev); } } } return(false); }
/// <summary> /// Override to perform custom dependency injection, the default one loops through the field of non-primitive types and injects on those. /// Return true if the injection handled already by your code and should not continue /// </summary> protected virtual bool DoInjectApplication(IApplicationDependencyInjector injector) { foreach (var fdef in Schema) { var v = GetFieldValue(fdef); if (v == null) { continue; } if (v is Doc vdoc) { injector.App.InjectInto(vdoc); } else if (v is IDictionary vdict) { foreach (var dv in vdict.Values) { if (dv == null) { continue; } if (dv.GetType().IsValueType) { continue; } injector.App.InjectInto(dv); } } else if (v is IEnumerable vedoc) { foreach (var ev in vedoc) { if (ev == null) { continue; } if (ev.GetType().IsValueType) { continue; } injector.App.InjectInto(ev); } } } return(false); }
/// <summary> /// System code not intended to be used by business apps. /// Applies attribute with auto-scoping rules - the system tries to detect /// what is trying to be injected based on the supplied type of the field. /// Return true if assignment was made /// </summary> public bool Apply(object target, FieldInfo fInfo, IApplicationDependencyInjector injector) { var tf = fInfo.FieldType; if (Type != null && !tf.IsAssignableFrom(Type)) { throw new DependencyInjectionException(StringConsts.DI_ATTRIBUTE_TYPE_INCOMPATIBILITY_ERROR.Args( Type.DisplayNameWithExpandedGenericArgs(), target.GetType().DisplayNameWithExpandedGenericArgs(), fInfo.ToDescription())); } try { return(DoApply(target, fInfo, injector)); } catch (Exception error) { throw new DependencyInjectionException(StringConsts.DI_ATTRIBUTE_APPLY_ERROR.Args( GetType().Name, target.GetType().DisplayNameWithExpandedGenericArgs(), fInfo.ToDescription(), error.ToMessageWithType()), error); } }
protected override bool DoApply(object target, FieldInfo fInfo, IApplicationDependencyInjector injector) => TryInjectAppRootObjects(target, fInfo, injector);
/// <summary> /// Enumerates app injectable roots (root application chassis objects) /// </summary> protected virtual IEnumerable <object> GetApplicationRoots(IApplicationDependencyInjector injector) => injector.GetApplicationRoots(); //the default clones roots from the injector
/// <summary> /// Tries to inject app root object (such as Log, Glue etc.) returning true on a successful assignment. /// The default implementation trips on a first match /// </summary> protected virtual bool TryInjectAppRootObjects(object target, FieldInfo fInfo, IApplicationDependencyInjector injector) { var tf = fInfo.FieldType; var needType = Type == null ? tf : Type; foreach (var appRoot in GetApplicationRoots(injector)) { if (needType.IsAssignableFrom(appRoot.GetType()))//trips on first match { if (Name.IsNotNullOrWhiteSpace() && appRoot is INamed named) { if (!Name.EqualsIgnoreCase(named.Name)) { continue; } } fInfo.SetValue(target, appRoot); return(true); } } return(false); }
protected override bool DoApply(object target, FieldInfo fInfo, IApplicationDependencyInjector injector) { return(TryInjectModule(target, fInfo, injector)); }
/// <summary> /// Override to perform custom DI, the default implementation injects content into all child modules. /// The DI is done before DoApplicationAfterInit() call by app chassis /// </summary> protected virtual bool DoInjectApplication(IApplicationDependencyInjector injector) { ChildModules.OrderedValues.ForEach(m => injector.InjectInto(m)); //Inject into all children return(false); //injection not completed, let the system keep processing [Inject] attributes }
bool IApplicationInjection.InjectApplication(IApplicationDependencyInjector injector) => DoInjectApplication(injector);
public bool InjectApplication(IApplicationDependencyInjector injector) { InjectorSID = injector.ComponentSID; return(false);//not completed keep injecting }
public bool InjectApplication(IApplicationDependencyInjector injector) { AppInjectedByHand = injector.App; InjectorSID = injector.ComponentSID; return(true);//completed do not inject anything else }
protected override bool DoInjectApplication(IApplicationDependencyInjector injector) { DI_COUNT++; return(base.DoInjectApplication(injector)); }
bool IApplicationInjection.InjectApplication(IApplicationDependencyInjector injector) { var completed = DoInjectApplication(injector); return(completed); }