public void SetSingletonLocator() { var locator = Locator; Locator = (tree) => { var type = ExportType(tree); var singleton = (Scope as DependencyInjectionContainer).Singletons.GetOrAdd(type, t => { tree.Key = new ActivatorKey(type, null); return(locator(tree)( RuntimeImportContext.GetStatic(null, tree.Context.ImportType), null)); }); return((ric, a) => singleton); }; }
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); } }
public T Locate <T>(object target, IImportContext ctx) => (T)Locate(RuntimeImportContext.GetStatic(target, ctx));
public T Locate <T>(object target = null) => (T)Locate(RuntimeImportContext.GetStatic(target, typeof(T)));
public object Locate(Type type, object target = null) => Locate(RuntimeImportContext.GetStatic(target, type));