Example #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)));
        }
Example #2
0
        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;
            });
        }
Example #4
0
        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;
            });
        }
Example #5
0
        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");
        }
    }
Example #6
0
 public bool Test(IActivatorTree tree) => _condition?.Invoke(tree) ?? true;
Example #7
0
 public IActivatorKey GetActivatorKey(IActivatorTree tree) => new ActivatorKey(ExportType(tree), tree.Context.Signature);
Example #8
0
        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");
            }
        }
Example #9
0
        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");
        }
Example #15
0
 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");
     }
 }
Example #16
0
 public ActivatorTree(IActivatorTree parent, IImportContext <T> context) : base(parent, context)
 {
 }