示例#1
0
        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);
            }
        }