示例#1
0
        /// <summary>
        /// Make asynchronous call in <see cref="Machine"/> context.
        /// </summary>
        /// <typeparam name="TResult">The type of the result.</typeparam>
        /// <param name="calledObject">The called object.</param>
        /// <param name="callName">Name of the call.</param>
        /// <param name="callback">The callback called after call is finished.</param>
        /// <param name="passedArgs">The passed arguments.</param>
        /// <exception cref="System.Collections.Generic.KeyNotFoundException">Cannot found method:  + callName + , on  + calledObject</exception>
        /// <exception cref="System.NotSupportedException">Cannot process async call on ambiguous method:  + callName + , on + calledObject</exception>
        protected void AsyncCall <TResult>(Instance calledObject, string callName, Action <TResult> callback = null, params Instance[] passedArgs)
        {
            var searcher = Services.CreateSearcher();

            searcher.ExtendName(calledObject.Info.TypeName);

            searcher.Dispatch(callName);

            if (!searcher.HasResults)
            {
                throw new KeyNotFoundException("Cannot found method: " + callName + ", on " + calledObject);
            }

            var foundMethods    = searcher.FoundResult;
            var matchingMethods = (from method in foundMethods where method.Parameters.Length == passedArgs.Length select method).ToArray();

            if (matchingMethods.Length > 1)
            {
                throw new NotSupportedException("Cannot process async call on ambiguous method: " + callName + ", on" + calledObject);
            }


            var edits = Edits;

            var callGenerator = new DirectedGenerator((e) =>
            {
                var thisArg = e.GetTemporaryVariable();

                var argVars = new List <string>();
                foreach (var passedArg in passedArgs)
                {
                    var argVar = e.GetTemporaryVariable();

                    e.AssignInstance(argVar, passedArg, passedArg.Info);
                    argVars.Add(argVar);
                }

                e.AssignArgument(thisArg, calledObject.Info, 1);
                e.Call(matchingMethods[0].MethodID, thisArg, Arguments.Values(argVars));

                if (callback != null)
                {
                    var callReturn = e.GetTemporaryVariable();
                    e.AssignReturnValue(callReturn, TypeDescriptor.Create <object>());

                    e.DirectInvoke((context) =>
                    {
                        var callValue = context.GetValue(new VariableName(callReturn));
                        var unwrapped = Unwrap <TResult>(callValue);

                        context.InjectEdits(edits);
                        Invoke(context, (c) => callback(unwrapped));
                    });
                }
            });


            Context.DynamicCall(callName, callGenerator, This, calledObject);
        }
示例#2
0
        /// <summary>
        /// Push call on stack of <see cref="Machine"/> that is invoked
        /// after all async methods are finished.
        /// </summary>
        /// <param name="callback">The callback called after async methods are finished.</param>
        protected void ContinuationCall(DirectMethod callback)
        {
            var callGenerator = new DirectedGenerator((e) =>
            {
                e.DirectInvoke((c) =>
                               Invoke(c, callback)
                               );
            });

            Context.DynamicCall("DirectAsyncCall", callGenerator, This);
        }
        public SimpleAssemblyProvider(string testFileFullPath)
        {
            //uchováme cestu k "definujícímu" souboru
            _fullPath = testFileFullPath;

            //jméno assembly odvodíme od názvu souboru
            _name = Path.GetFileName(_fullPath);

            //připravíme kontejner kam vložíme definovanou metodu
            _methods = new HashedMethodContainer();

            //vytvoření metody začneme přípravou typu, kde je definovaná
            _declaringType = TypeDescriptor.Create("MEFEditor.ProviderTest");
            //určíme jméno metody
            var methodName = "GetDefiningAssemblyName";
            //návratový typ metody
            var returnType = TypeDescriptor.Create <string>();

            //z definovaných údajů můžeme vytvořit popis
            //metody, která nebude mít žádné parametry a bude statická
            var methodInfo = new TypeMethodInfo(
                _declaringType, methodName, returnType,
                ParameterTypeInfo.NoParams,
                isStatic: true,
                methodTypeArguments: TypeDescriptor.NoDescriptors);

            //k dokončení definice metody stačí vytvořit
            //generátor jejích analyzačních instrukcí
            var methodGenerator = new DirectedGenerator(emitDirector);

            //definovanou metodu vytvoříme
            var method = new MethodItem(methodGenerator, methodInfo);

            //aby byla metoda dohledatelná, musíme ji ještě zaregistrovat
            _methods.AddItem(method);
        }