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))); }
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); } }