private DependencyLocator GetActivator(IActivatorTree tree) { var key = new ActivatorKey(ExportType(tree), tree.Context.Signature); tree.Key = key; #if DEBUG Debug.WriteLine(tree.TabbedBranch()); #endif return(_activators.GetOrAdd(key, k => GetNewClassActivator(tree))); }
public string ReadableTree() { string s = ""; IActivatorTree node = this; while (node != null) { s = node.ToString() + "\n" + s; node = node.Parent; } return(s); }
private DependencyLocator GetNewLocator_IEnumerable_1 <T>(IActivatorTree tree) { Action <IRuntimeImportContext, object[], List <T> > action = (c, a, l) => {}; var testTree = new ActivatorTree(tree, tree.Context.Get(typeof(T))); foreach (var e in _locatorEntries.Where(l => l.Test(testTree)).ToList()) { var activator = e.Locator(new ActivatorTree(tree, tree.Context.Get(typeof(T)))); action += (c, a, l) => l.Add((T)activator(c, a)); } return((c, a) => { var l = new List <T>(); action(c, a, l); return l; }); }
private DependencyLocator GetNewClassActivator(IActivatorTree tree) { var ctor = tree.Key.GetConstructor(); var type = tree.Key.ReturnType; var inject = Scope.GetClassInjector(tree); DependencyInjector locator = inject.Item1; if (ctor != null) { if (ctor.GetParameters().Length > 0) { locator += (ctx, args, o) => ctor.Invoke(o, args); } else if (inject.Item2 == null) { locator += (ctx, args, o) => ctor.Invoke(o, null); } else { locator += inject.Item2; } } else { locator += inject.Item2; } locator += inject.Item3; return((c, args) => { var o = FormatterServices.GetUninitializedObject(type); c = c.Get(o); locator?.Invoke(c, args, o); return o; }); }
public DependencyInjector GetActivator(Func <IActivatorTree, DependencyLocator> getLocatorFunc, IActivatorTree tree) { if (tree.Context.TargetMemberInfo is ConstructorInfo ci) { Action <IRuntimeImportContext, object[], object[]> setParameters = null; var i = 0; foreach (var parameterInfo in ci.GetParameters()) { var ctx = tree.Context = tree.Context.Get(parameterInfo.ParameterType); var locator = getLocatorFunc(tree); var pos = i; setParameters += (c, a, o) => o[pos] = locator(c.Get(o, ctx), a); i++; } var nb = i; if (setParameters != null) { return (c, a, o) => { var param = new object[nb]; setParameters.Invoke(c, a, param); ci.Invoke(o, param); } } ; return((c, a, o) => ci.Invoke(o, new object[0])); } throw new InvalidOperationException(tree.Context.TargetMemberInfo.Name + "is not constructor"); } }
public bool Test(IActivatorTree tree) => _condition?.Invoke(tree) ?? true;
public IActivatorKey GetActivatorKey(IActivatorTree tree) => new ActivatorKey(ExportType(tree), tree.Context.Signature);
public DependencyInjector GetActivator(Func <IActivatorTree, IDependencyLocator> getLocator, IActivatorTree tree) { if (tree.Context.TargetMemberInfo is MethodInfo mi) { Action <IRuntimeImportContext, object[], object[]> setParameters = (c, a, o) => { }; var i = 0; foreach (var parameterInfo in mi.GetParameters()) { var methodCtx = tree.Context = tree.Context.CreateChild(parameterInfo.ParameterType); var methodActivator = getLocator(tree); var pos = i; setParameters += (c, a, o) => o[pos] = methodActivator.Locate(c.NewChild(o, methodCtx), a); i++; } var nb = i; return((c, a, o) => { var param = new object[nb]; setParameters(c, a, param); mi.Invoke(o, param); }); } else { throw new InvalidOperationException(tree.Context.TargetMemberInfo.Name + "is not method"); } }
public virtual DependencyInjector GetActivator(Func <IActivatorTree, DependencyLocator> getLocator, IActivatorTree tree) { if (tree.Context.TargetMemberInfo is PropertyInfo pi) { if (pi.CanWrite) { var propertyCtx = tree.Context = tree.Context.Get(pi.PropertyType); var propertyActivator = getLocator(tree); return((c, a, o) => { var propertyInfo = pi; var value = propertyActivator(c.Get(o, propertyCtx), a); propertyInfo.SetValue(o, value); }); } else { var fi = GetBackingField(pi); if (fi == null) { throw new Exception("Property " + pi.Name + " in " + tree.Context.TargetType.Name + " not writable"); } var autoCtx = tree.Context = tree.Context.Get(fi.FieldType); var autoActivator = getLocator(tree); return((c, args, target) => { var value = autoActivator(c.Get(target, autoCtx), args); fi.SetValue(target, value); }); } } else { throw new InvalidOperationException(tree.Context.TargetMemberInfo.Name + "is not property"); } }
public Tuple <DependencyInjector, DependencyInjector, DependencyInjector> GetClassInjector(IActivatorTree tree) => _injectors.GetOrAdd(tree.Key.ReturnType, t => GetNewClassInjector(tree));
private Tuple <DependencyInjector, DependencyInjector, DependencyInjector> GetNewClassInjector(IActivatorTree tree) { var type = tree.Key.ReturnType; if (type.IsAbstract) { throw new Exception("Unable to locate Abstract class : " + type.Name); } if (type.IsInterface) { throw new Exception("Unable to locate Interface : " + type.Name); } DependencyInjector activator = null; DependencyInjector activatorCtor = null; DependencyInjector activatorAfter = null; var types = new Stack <Type>(); var t = type; while (t != null) { types.Push(t); t = t.BaseType; } while (types.Count > 0) { t = types.Pop(); foreach (var p in t.GetMembers(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public)) { foreach (var attr in p.GetCustomAttributes <ImportAttribute>()) { var ctx = ImportContext.Get(type, p).Get(typeof(IActivator)); var l = GetLocator(new ActivatorTree(tree, ctx)); var a = (IActivator)(l(RuntimeImportContext.GetStatic(null, ctx), null)); if (p is ConstructorInfo ci) { activatorCtor = a.GetActivator(GetLocator, new ActivatorTree(tree, ImportContext.Get(type, p))); } else { switch (attr.Location) { case InjectLocation.BeforeConstructor: activator += a.GetActivator(GetLocator, new ActivatorTree(tree, ImportContext.Get(type, p))); break; case InjectLocation.AfterConstructor: activatorAfter += a.GetActivator(GetLocator, new ActivatorTree(tree, ImportContext.Get(type, p))); break; default: break; } } } } } if (typeof(IInitializer).IsAssignableFrom(type)) { activator += (ctx, args, o) => _initializerMethodInfo.Invoke(o, new object [] { ctx, args }); } foreach (var k in _initializers) { if (k.Key.IsAssignableFrom(type)) { foreach (var action in k.Value) { activator += action; } } } return(new Tuple <DependencyInjector, DependencyInjector, DependencyInjector>(activator, activatorCtor, activatorAfter)); }
private DependencyLocator GetNewLocator(IActivatorTree tree) { var importType = tree.Context.ImportType; if (importType.IsGenericType) { var g = importType.GetGenericTypeDefinition(); var args = importType.GetGenericArguments(); // return a Func<Type,object> to provide generic locator without arguments if (args.Length == 2 && args[0] == typeof(Type) && args[1] == typeof(object)) { return((c, a) => new Func <Type, object>(t => Locate(c.Get(c.Target, tree.Context.Get(t, null))))); } //return a Func<Type,object[],object> to provide a generic locator with arguments if (args.Length == 3 && args[0] == typeof(Type) && args[1] == typeof(object[]) && args[2] == typeof(object)) { return((c, a) => new Func <Type, object[], object>((t, ar) => { var types = new MethodSignature(ar); return Locate(c.Get(c.Target, tree.Context.Get(t, types)), ar); })); } var name = g.Name.Split('`')[0]; var mi = GetType().GetMethod("GetNewLocator_" + name + "_" + args.Length, BindingFlags.NonPublic | BindingFlags.Instance); if (mi != null) { var m = mi.MakeGenericMethod(args); var r = m?.Invoke(this, new object[] { tree }); if (r is DependencyLocator l) { return(l); } throw new Exception(""); } } { var decorators = _decoratorEntries.Where(e => e.Test(tree)); var exportEntry = _locatorEntries.Get(e => e.Test(tree)); //if (tree.Context.ImportType.Name.Contains("ErpServices")) //{ // foreach (var e in _locatorEntries) // { // if (e.ExportType(tree).Name.Contains("ErpServices")) // { } // var r = e.Test(tree); // } //} IActivatorKey export; ExportMode mode; // when no export entry found but type is instantiable use it TODO : should be an option if (exportEntry == null) { if (!importType.IsAbstract && !importType.IsInterface) { exportEntry = new ExportEntry(this) { ExportType = t => importType }; export = new ActivatorKey(importType, tree.Context.Signature); mode = ExportMode.Default; } else { var t = new ActivatorTree(null, new ImportContext()); var n = _locatorEntries.Get(e => { try { var exportType = e.ExportType(t); return(importType.IsAssignableFrom(exportType)); } catch { return(false); } }); throw new Exception("Unable to locate " + tree.ToString() /*importType.GenericReadableName()*/); } } else { export = exportEntry.GetActivatorKey(tree); mode = exportEntry.Mode; } DependencyLocator activator; if (mode.HasFlag(ExportMode.Singleton)) { var type = export.ReturnType; tree.Key = new ActivatorKey(type, null); var singleton = Singletons.GetOrAdd(type, t => exportEntry.Locator(tree)(RuntimeImportContext.GetStatic(null, tree.Context.ImportType), null)); activator = (c, a) => singleton; } else { activator = exportEntry.Locator(tree); } foreach (var de in decorators) { var decorator = de.Locator(new ActivatorTree(tree, tree.Context.Get(importType, new MethodSignature(importType)))); var old = activator; activator = (c, a) => decorator(c, new[] { old(c, a) }); } return(activator); } }
private DependencyLocator GetLocator(IActivatorTree tree) => _locators.GetOrAdd(tree.Context, c => GetNewLocator(tree));
public override DependencyInjector GetActivator(Func <IActivatorTree, DependencyLocator> getLocator, IActivatorTree tree) { if (tree.Context.TargetMemberInfo is PropertyInfo pi) { if (pi.CanWrite) { return(base.GetActivator(getLocator, tree)); } var backingField = GetBackingField(pi); var propertyCtx = tree.Context.Get(pi.PropertyType, null); var propertyActivator = getLocator(new ActivatorTree(tree, propertyCtx)); var getPropertyEntry = GetPropertyEntryInfo.MakeGenericMethod(pi.PropertyType); if (backingField != null) { return((c, args, target) => { var value = propertyActivator(c.Get(target, propertyCtx), args); backingField.SetValue(target, value); var notifier = (target as INotifierObject)?.GetNotifier(); if (notifier != null) { var prm = new object[] { pi }; var entry = getPropertyEntry.Invoke(notifier, prm); SetInitialValueInfo.Invoke(entry, new[] { value }); return; } throw new Exception("No notifier available "); }); } else { return((c, args, target) => { var notifier = (target as INotifierObject)?.GetNotifier(); if (notifier != null) { var prm = new object[] { pi }; var entry = getPropertyEntry.Invoke(notifier, prm); var value = propertyActivator(c.Get(target, propertyCtx), args); SetInitialValueInfo.Invoke(entry, new[] { value }); return; } throw new Exception("No notifier available "); }); } } throw new Exception(tree.Context.TargetMemberInfo.Name + " is not a property"); }
public DependencyInjector GetActivator(Func <IActivatorTree, DependencyLocator> getLocator, IActivatorTree tree) { if (tree.Context.TargetMemberInfo is FieldInfo fi) { var fieldCtx = tree.Context = tree.Context.Get(fi.FieldType); var fieldActivator = getLocator(tree); return((c, a, o) => { var value = fieldActivator(c.Get(o, fieldCtx), a); fi.SetValue(o, value); }); } else { throw new InvalidOperationException(tree.Context.TargetMemberInfo.Name + "is not field"); } }
public ActivatorTree(IActivatorTree parent, IImportContext <T> context) : base(parent, context) { }