/// <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); }
/// <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); }