Example #1
0
        public virtual void AddToDictionary(object instance, object key, object item)
        {
            if (instance == null)
            {
                throw new ArgumentNullException("instance");
            }

            var instanceType = instance.GetType();

            var lookupKey = Tuple.Create(instanceType, key?.GetType(), item?.GetType());

            var mode = Type?.SchemaContext.InvokerOptions ?? XamlInvokerOptions.None;

            if (mode.HasFlag(XamlInvokerOptions.Compile))
            {
                Action <object, object, object> addDelegate;
                if (TryGetCache(lookupKey, out addDelegate))
                {
                    addDelegate(instance, key, item);
                    return;
                }

                MethodInfo mi = LookupAddDictionaryMethod(instanceType);
                if (mi == null)
                {
                    throw new InvalidOperationException($"The dictionary type '{instanceType}' does not have 'Add' method");
                }
                if (mode.HasFlag(XamlInvokerOptions.DeferCompile))
                {
                    addDelegate = (i, k, v) => mi.Invoke(i, new object[] { k, v });
                    Task.Factory.StartNew(() => cache[key] = addDelegate = mi.BuildCall2Expression());
                }
                else
                {
                    addDelegate = mi.BuildCall2Expression();
                }
                cache[lookupKey] = addDelegate;
                addDelegate(instance, key, item);
            }
            else
            {
                MethodInfo mi;
                if (TryGetCache(lookupKey, out mi))
                {
                    mi.Invoke(instance, new object[] { key, item });
                    return;
                }

                mi = LookupAddDictionaryMethod(instanceType);
                if (mi == null)
                {
                    throw new InvalidOperationException($"The dictionary type '{instanceType}' does not have 'Add' method");
                }
                cache[lookupKey] = mi;
                mi.Invoke(instance, new object [] { key, item });
            }
        }