Beispiel #1
0
        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));