public void GetType_should_return_mapped_type_when_type_is_registered() { var typeDescription = new TypeDescription("test", new IPropertyDescription[0]); var generatedType = new GeneratedType("test", typeof(int), typeDescription); typeMapper.RegisterNewType(typeDescription, generatedType); var result = typeMapper.GetType(this.GetType()); Assert.AreEqual(result, this.GetType()); }
private GeneratedType buildSourceType(GeneratedAssembly assembly, CompiledSourceType handlerType, GeneratedType compiledHandlerType) { var sourceBaseType = typeof(CompiledQuerySource <,>).MakeGenericType(_plan.OutputType, _plan.QueryType); var sourceName = _plan.QueryType.Name + "CompiledQuerySource"; var sourceType = assembly.AddType(sourceName, sourceBaseType); var hardcoded = new InjectedField(typeof(HardCodedParameters), "hardcoded"); sourceType.AllInjectedFields.Add(hardcoded); var buildHandler = sourceType.MethodFor("BuildHandler"); switch (handlerType) { case CompiledSourceType.Cloneable: var innerField = new InjectedField(typeof(IMaybeStatefulHandler)); sourceType.AllInjectedFields.Add(innerField); var statistics = _plan.StatisticsMember == null ? "null" : $"query.{_plan.StatisticsMember.Name}"; buildHandler.Frames.Code( $"return new Marten.Generated.{compiledHandlerType.TypeName}({innerField.Usage}, query, {statistics}, _hardcoded);"); break; case CompiledSourceType.Stateless: var inner = new InjectedField(typeof(IQueryHandler <>).MakeGenericType(_plan.OutputType)); sourceType.AllInjectedFields.Add(inner); buildHandler.Frames.Code( $"return new Marten.Generated.{compiledHandlerType.TypeName}({inner.Usage}, query, _hardcoded);"); break; case CompiledSourceType.Complex: var innerField2 = new InjectedField(typeof(IMaybeStatefulHandler)); sourceType.AllInjectedFields.Add(innerField2); buildHandler.Frames.Code( $"return new Marten.Generated.{compiledHandlerType.TypeName}({innerField2.Usage}, query, _hardcoded);"); break; } return(sourceType); }
private void buildLoaderCommands(GeneratedType type) { var load = type.MethodFor("BuildLoadCommand"); var loadByArray = type.MethodFor("BuildLoadManyCommand"); if (_mapping.TenancyStyle == TenancyStyle.Conjoined) { load.Frames.Code( "return new NpgsqlCommand(_loaderSql).With(\"id\", id).With(TenantIdArgument.ArgName, tenant.TenantId);"); loadByArray.Frames.Code( "return new NpgsqlCommand(_loadArraySql).With(\"ids\", ids).With(TenantIdArgument.ArgName, tenant.TenantId);"); } else { load.Frames.Code("return new NpgsqlCommand(_loaderSql).With(\"id\", id);"); loadByArray.Frames.Code("return new NpgsqlCommand(_loadArraySql).With(\"ids\", ids);"); } }
public GeneratedType AddType(string typeName, Type baseType) { // TODO -- assert that it's been generated already? var generatedType = new GeneratedType(Generation, typeName); if (baseType.IsInterface) { generatedType.Implements(baseType); } else { generatedType.InheritsFrom(baseType); } GeneratedTypes.Add(generatedType); return(generatedType); }
public DefaultAggregateConstruction(Type returnType, GeneratedType generatedType) { _returnType = returnType; _constructor = returnType.GetConstructor( BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null); if (_constructor != null && !_constructor.IsPublic) { var ctor = Expression.New(_constructor); var lambda = Expression.Lambda(ctor); var func = lambda.Compile(); _setter = new Setter(func.GetType(), "AggregateBuilder") { InitialValue = func }; generatedType.Setters.Add(_setter); } }
private void buildConfigureMethod(GeneratedType type) { var method = type.MethodFor("ConfigureParameters"); var parameters = method.Arguments[0]; var arguments = _function.OrderedArguments(); for (var i = 0; i < arguments.Length; i++) { var argument = arguments[i]; argument.GenerateCodeToModifyDocument(method, type, i, parameters, _mapping, _options); } for (var i = 0; i < arguments.Length; i++) { var argument = arguments[i]; argument.GenerateCodeToSetDbParameterValue(method, type, i, parameters, _mapping, _options); } }
private static GeneratedType buildUpdateStreamVersion(GeneratedType builderType, GeneratedAssembly assembly, EventGraph graph) { var operationType = assembly.AddType(UpdateStreamVersionOperationName, typeof(UpdateStreamVersion)); var sql = $"update {graph.DatabaseSchemaName}.mt_streams set version = ? where id = ? and version = ?"; if (graph.TenancyStyle == TenancyStyle.Conjoined) { sql += $" and {TenantIdColumn.Name} = ?"; } var configureCommand = operationType.MethodFor("ConfigureCommand"); configureCommand.DerivedVariables.Add(new Variable(typeof(StreamAction), nameof(UpdateStreamVersion.Stream))); configureCommand.Frames.Code($"var parameters = {{0}}.{nameof(CommandBuilder.AppendWithParameters)}(\"{sql}\");", Use.Type <CommandBuilder>()); configureCommand.SetParameterFromMember <StreamAction>(0, x => x.Version); if (graph.StreamIdentity == StreamIdentity.AsGuid) { configureCommand.SetParameterFromMember <StreamAction>(1, x => x.Id); } else { configureCommand.SetParameterFromMember <StreamAction>(1, x => x.Key); } configureCommand.SetParameterFromMember <StreamAction>(2, x => x.ExpectedVersionOnServer); if (graph.TenancyStyle == TenancyStyle.Conjoined) { new TenantIdColumn().As <IStreamTableColumn>().GenerateAppendCode(configureCommand, 3); } builderType.MethodFor(nameof(EventDocumentStorage.UpdateStreamVersion)) .Frames.Code($"return new Marten.Generated.{UpdateStreamVersionOperationName}({{0}});", Use.Type <StreamAction>()); return(operationType); }
private void buildLiveAggregationType() { var liveBaseType = _isAsync ? typeof(AsyncLiveAggregatorBase <>) : typeof(SyncLiveAggregatorBase <>); liveBaseType = liveBaseType.MakeGenericType(typeof(T)); _liveType = _assembly.AddType(GetType().NameInCode().Sanitize() + "LiveAggregation", liveBaseType); var overrideMethodName = _isAsync ? "BuildAsync" : "Build"; var buildMethod = _liveType.MethodFor(overrideMethodName); buildMethod.DerivedVariables.Add(Variable.For <IQuerySession>("(IQuerySession)session")); buildMethod.Frames.Code("if (!events.Any()) return null;"); var callCreateAggregateFrame = new CallCreateAggregateFrame(_createMethods); // This is the existing snapshot passed into the LiveAggregator var snapshot = buildMethod.Arguments.Single(x => x.VariableType == typeof(T)); callCreateAggregateFrame.CoalesceAssignTo(snapshot); buildMethod.Frames.Add(callCreateAggregateFrame); buildMethod.Frames.Add(new CallApplyAggregateFrame(_applyMethods) { InsideForEach = true }); buildMethod.Frames.Return(typeof(T)); _liveType.AllInjectedFields.Add(new InjectedField(GetType())); _createMethods.BuildCreateMethod(_liveType, _aggregateMapping); _applyMethods.BuildApplyMethod(_liveType, _aggregateMapping); _liveType.Setters.AddRange(_applyMethods.Setters()); _liveType.Setters.AddRange(_createMethods.Setters()); _liveType.Setters.AddRange(_shouldDeleteMethods.Setters()); }
public static string InitializeLambdaSetterProperty(this GeneratedType generatedType, MemberInfo member, Type documentType) { var setterFieldName = $"{member.Name}Writer"; if (generatedType.Setters.All(x => x.PropName != setterFieldName)) { var memberType = member.GetRawMemberType(); var actionType = typeof(Action <,>).MakeGenericType(documentType, memberType); var expression = $"{typeof(LambdaBuilder).GetFullName()}.{nameof(LambdaBuilder.Setter)}<{documentType.FullNameInCode()},{memberType.FullNameInCode()}>(typeof({documentType.FullNameInCode()}).GetProperty(\"{member.Name}\"))"; var constant = new Variable(actionType, expression); var setter = Setter.StaticReadOnly(setterFieldName, constant); generatedType.Setters.Add(setter); } return(setterFieldName); }
public void GenerateResolver(GeneratedAssembly generatedAssembly) { if (_resolverType != null) return; // got some kind of loop in here we need to short circuit if (ErrorMessages.Any() || Dependencies.SelectMany(x => x.ErrorMessages).Any()) return; var typeName = (ServiceType.FullNameInCode() + "_" + Name).Sanitize(); var buildType = ServiceType.MustBeBuiltWithFunc() || ImplementationType.MustBeBuiltWithFunc() ? typeof(object) : ServiceType; _resolverType = generatedAssembly.AddType(typeName, ResolverBaseType.MakeGenericType(buildType)); var method = _resolverType.MethodFor("Build"); var frame = CreateBuildFrame(); method.Frames.Add(frame); }
private void writeReturnOfOperation(GeneratedMethod method, GeneratedType operationType) { var assembly = method.ParentType.ParentAssembly; var tenantDeclaration = ""; if (_mapping.TenancyStyle == TenancyStyle.Conjoined) { tenantDeclaration = ", tenant"; } if (_mapping.IsHierarchy()) { method.Frames .Code($@" return new {assembly.Namespace}.{operationType.TypeName} ( {{0}}, Identity({{0}}), {{1}}.Versions.ForType<{_mapping.DocumentType.FullNameInCode()}, {_mapping.IdType.FullNameInCode()}>(), {{2}} {tenantDeclaration} );" , new Use(_mapping.DocumentType), Use.Type <IMartenSession>(), Use.Type <DocumentMapping>()); } else { method.Frames .Code($@" return new {assembly.Namespace}.{operationType.TypeName} ( {{0}}, Identity({{0}}), {{1}}.Versions.ForType<{_mapping.DocumentType.FullNameInCode()}, {_mapping.IdType.FullNameInCode()}>(), {{2}} {tenantDeclaration} );" , new Use(_mapping.DocumentType), Use.Type <IMartenSession>(), Use.Type <DocumentMapping>()); } }
private void buildStorageOperationMethods(DocumentOperations operations, GeneratedType type) { if (_mapping.UseOptimisticConcurrency) { buildConditionalOperationBasedOnConcurrencyChecks(type, operations, "Upsert"); buildOperationMethod(type, operations, "Insert"); buildOperationMethod(type, operations, "Overwrite"); buildConditionalOperationBasedOnConcurrencyChecks(type, operations, "Update"); } else { buildOperationMethod(type, operations, "Upsert"); buildOperationMethod(type, operations, "Insert"); buildOperationMethod(type, operations, "Update"); } if (_mapping.UseOptimisticConcurrency) { buildOperationMethod(type, operations, "Overwrite"); } else { type.MethodFor("Overwrite").Frames.ThrowNotSupportedException(); } type.MethodFor("DeleteForDocument").Frames.Code($@" return new Marten.Generated.{operations.DeleteById.TypeName}(Identity({{0}})); ", new Use(_mapping.DocumentType)); type.MethodFor("DeleteForId").Frames.Code($@" return new Marten.Generated.{operations.DeleteById.TypeName}({{0}}); ", new Use(_mapping.IdType)); type.MethodFor("DeleteForWhere").Frames.Code($@" return new Marten.Generated.{operations.DeleteByWhere.TypeName}({{0}}); ", Use.Type <IWhereFragment>()); }
private void Initialise() { var newTypeName = Guid.NewGuid().ToString(); var assemblyName = new AssemblyName(newTypeName); var dynamicAssembly = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run); var dynamicModule = dynamicAssembly.DefineDynamicModule("Main"); var dynamicType = dynamicModule.DefineType(newTypeName, TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.AutoClass | TypeAttributes.AnsiClass | TypeAttributes.BeforeFieldInit | TypeAttributes.AutoLayout, typeof(T)); dynamicType.DefineDefaultConstructor(MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName); foreach (var property in Properties) { AddProperty(dynamicType, property.Key, property.Value); } GeneratedType = dynamicType.CreateType(); foreach (var property in Properties) { var propertyInfo = GeneratedType.GetProperty(property.Key); var setMethod = propertyInfo.GetSetMethod(); if (setMethod == null) { continue; } _setMethods.Add(property.Key, setMethod); } }
private void buildPostprocessingMethods(GeneratedType type) { var sync = type.MethodFor(nameof(IStorageOperation.Postprocess)); var @async = type.MethodFor(nameof(IStorageOperation.PostprocessAsync)); void applyVersionToDocument() { if (_mapping.VersionMember != null) { var code = $"_document.{_mapping.VersionMember.Name} = _version;"; sync.Frames.Code(code); async.Frames.Code(code); } } if (_mapping.UseOptimisticConcurrency) { @async.AsyncMode = AsyncMode.AsyncTask; @async.Frames.CodeAsync("BLOCK:if (await postprocessConcurrencyAsync({0}, {1}, {2}))", Use.Type <DbDataReader>(), Use.Type <IList <Exception> >(), Use.Type <CancellationToken>()); @sync.Frames.Code("BLOCK:if (postprocessConcurrency({0}, {1}))", Use.Type <DbDataReader>(), Use.Type <IList <Exception> >()); applyVersionToDocument(); @async.Frames.Code("END"); @sync.Frames.Code("END"); } else { sync.Frames.Code("storeVersion();"); async.Frames.Code("storeVersion();"); applyVersionToDocument(); } @async.AsyncMode = AsyncMode.ReturnCompletedTask; @async.Frames.Add(new CommentFrame("Nothing")); }
private void configureCommandMethod(GeneratedType compiledType, HardCodedParameters hardcoded) { var method = compiledType.MethodFor(nameof(IQueryHandler.ConfigureCommand)); method.Frames.Code($"var parameters = {{0}}.{nameof(CommandBuilder.AppendWithParameters)}(@{{1}});", Use.Type <CommandBuilder>(), _plan.CorrectedCommandText()); foreach (var parameter in _plan.Parameters) { parameter.GenerateCode(method, _storeOptions); } if (hardcoded.HasTenantId) { method.Frames.Code($"{{0}}.{nameof(CommandBuilder.AddNamedParameter)}({{1}}, session.Tenant.TenantId);", Use.Type <CommandBuilder>(), TenantIdArgument.ArgName); } if (hardcoded.HasAny()) { method.Frames.Code($"_hardcoded.{nameof(HardCodedParameters.Apply)}(parameters);"); } }
protected override void assembleTypes(GeneratedAssembly assembly, StoreOptions options) { assembly.Rules.Assemblies.Add(GetType().Assembly); assembly.Rules.Assemblies.AddRange(_projectMethods.ReferencedAssemblies()); assembly.Rules.Assemblies.AddRange(_createMethods.ReferencedAssemblies()); assembly.UsingNamespaces.Add("System.Linq"); _isAsync = _createMethods.IsAsync || _projectMethods.IsAsync; var baseType = _isAsync ? typeof(AsyncEventProjection <>) : typeof(SyncEventProjection <>); baseType = baseType.MakeGenericType(GetType()); _inlineType = assembly.AddType(_inlineTypeName, baseType); var method = _inlineType.MethodFor("ApplyEvent"); method.DerivedVariables.Add(new Variable(GetType(), "Projection")); var eventHandling = MethodCollection.AddEventHandling(null, null, _createMethods, _projectMethods); method.Frames.Add(eventHandling); }
public override object GenerateValuesss1221(Func <Type, object> generate) { Type listType = GeneratedType.MakeGenericType(new[] { nestedType }); IList list = (IList)Activator.CreateInstance(listType); int amount = Random.Next(3, 5); if (generators.TryGetValue(nestedType, out Generator generator)) { for (int i = 0; i < amount; i++) { list.Add(generator.GenerateValue(generate)); } return(list); } else { for (int i = 0; i < amount; i++) { list.Add(generate(nestedType)); } return(list); } }
/// <summary> /// Generates the necessary setter code to set a value of a document. /// Handles internal/private setters /// </summary> /// <param name="frames"></param> /// <param name="member"></param> /// <param name="variableName"></param> /// <param name="documentType"></param> /// <param name="generatedType"></param> public static void SetMemberValue(this FramesCollection frames, MemberInfo member, string variableName, Type documentType, GeneratedType generatedType) { if (member is PropertyInfo property) { if (property.CanWrite) { if (property.SetMethod.IsPublic) { frames.SetPublicMemberValue(member, variableName, documentType); } else { var setterFieldName = generatedType.InitializeLambdaSetterProperty(member, documentType); frames.Code($"{setterFieldName}({{0}}, {variableName});", new Use(documentType)); } return; } } else if (member is FieldInfo field) { if (field.IsPublic) { frames.SetPublicMemberValue(member, variableName, documentType); } else { var setterFieldName = generatedType.InitializeLambdaSetterProperty(member, documentType); frames.Code($"{setterFieldName}({{0}}, {variableName});", new Use(documentType)); } return; } throw new ArgumentOutOfRangeException(nameof(member), $"MemberInfo {member} is not valid in this usage. "); }
private void buildHandlerMethod(GeneratedType compiledType) { var method = compiledType.MethodFor("BuildHandler"); var handlerName = "_inner"; // first build out the inner if (_plan.HandlerPrototype is IMaybeStatefulHandler h && h.DependsOnDocumentSelector()) { handlerName = "cloned"; var statistics = _plan.StatisticsMember == null ? "null" : $"query.{_plan.StatisticsMember.Name}"; method.Frames.Code( $"var cloned = _inner.{nameof(IMaybeStatefulHandler.CloneForSession)}(session, {statistics});"); } if (_plan.IncludeMembers.Any()) { var readers = _plan.IncludeMembers.Select(buildIncludeReader); var includeHandlerType = typeof(IncludeQueryHandler <>).MakeGenericType(_plan.OutputType); var readerArray = "{{" + readers.Join(", ") + "}}"; var constructorHandlerType = typeof(IQueryHandler <>).MakeGenericType(_plan.OutputType); method.Frames.Code( $"var includeWriters = new {typeof(IIncludeReader).FullNameInCode()}[]{readerArray};"); method.Frames.Code( $"var included = new {includeHandlerType.FullNameInCode()}(({constructorHandlerType.FullNameInCode()}){handlerName}, includeWriters);"); handlerName = "included"; } method.Frames.Code($"return {handlerName};"); }
private void buildAsyncDaemonAggregation() { var daemonBuilderIsAsync = _applyMethods.IsAsync || _createMethods.IsAsync || _shouldDeleteMethods.IsAsync; var baseType = (daemonBuilderIsAsync ? typeof(AsyncDaemonAggregationBase <,>) : typeof(SyncDaemonAggregationBase <,>)) .MakeGenericType(typeof(T), _aggregateMapping.IdType); _asyncDaemonType = _assembly.AddType(GetType().Name.Sanitize() + "AsyncDaemonAggregation", baseType); _asyncDaemonType.AllInjectedFields.Add(new InjectedField(_storageType)); var injectedField = new InjectedField(GetType()); _asyncDaemonType.AllInjectedFields.Add(injectedField); // Build the create method _createMethods.BuildCreateMethod(_asyncDaemonType, _aggregateMapping); buildDetermineOperationMethodForDaemonRunner(daemonBuilderIsAsync); _asyncDaemonType.Setters.AddRange(_applyMethods.Setters()); _asyncDaemonType.Setters.AddRange(_createMethods.Setters()); _asyncDaemonType.Setters.AddRange(_shouldDeleteMethods.Setters()); }
public void GenerateCode(StorageStyle storageStyle, GeneratedType generatedType, GeneratedMethod async, GeneratedMethod sync, int index, DocumentMapping mapping) { var versionPosition = index;//mapping.IsHierarchy() ? 3 : 2; async.Frames.CodeAsync($"var version = await reader.GetFieldValueAsync<System.Guid>({versionPosition}, token);"); sync.Frames.Code($"var version = reader.GetFieldValue<System.Guid>({versionPosition});"); if (storageStyle != StorageStyle.QueryOnly) { // Store it sync.Frames.Code("_versions[id] = version;"); async.Frames.Code("_versions[id] = version;"); } if (Member != null) { sync.Frames.SetMemberValue(Member, "version", mapping.DocumentType, generatedType); async.Frames.SetMemberValue(Member, "version", mapping.DocumentType, generatedType); } }
public override void GenerateBulkWriterCode(GeneratedType type, GeneratedMethod load, DocumentMapping mapping) { load.Frames.Code($"writer.Write(document.GetType().FullName, {{0}});", DbType); }
public override void GenerateCodeToSetDbParameterValue(GeneratedMethod method, GeneratedType type, int i, Argument parameters, DocumentMapping mapping, StoreOptions options) { method.Frames.Code($"{parameters.Usage}[{i}].{nameof(NpgsqlParameter.NpgsqlDbType)} = {{0}};", DbType); method.Frames.Code($"{parameters.Usage}[{i}].{nameof(NpgsqlParameter.Value)} = docType;"); }
public override void GenerateBulkWriterCode(GeneratedType type, GeneratedMethod load, DocumentMapping mapping) { load.Frames.Code($"writer.Write(tenant.TenantId, {{0}});", DbType); }
public override void GenerateCode(GeneratedMethod method, GeneratedType type, int i, Argument parameters, DocumentMapping mapping, StoreOptions options) { method.Frames.Code($"{{0}}[{{1}}].Value = {{2}}.{nameof(ITenant.TenantId)};", parameters, i, Use.Type <ITenant>()); method.Frames.Code("{0}[{1}].NpgsqlDbType = {2};", parameters, i, DbType); }
public override void GenerateCode(GeneratedMethod method, GeneratedType type, int i, Argument parameters, DocumentMapping mapping, StoreOptions options) { method.Frames.Code("setCurrentVersionParameter({0}[{1}]);", parameters, i); }
public override void GenerateBulkWriterCodeAsync(GeneratedType type, GeneratedMethod load, DocumentMapping mapping) { load.Frames.Code($"await writer.WriteAsync(document.GetType().FullName, {{0}}, {{1}});", DbType, Use.Type <CancellationToken>()); }
public override void GenerateCodeToSetDbParameterValue(GeneratedMethod method, GeneratedType type, int i, Argument parameters, DocumentMapping mapping, StoreOptions options) { var version = type.AllInjectedFields[0]; method.Frames.Code("// .Net Class Type"); method.Frames.Code("{0}[{1}].NpgsqlDbType = {2};", parameters, i, DbType); method.Frames.Code("{0}[{1}].Value = {2}.GetType().FullName;", parameters, i, version); }
private static void buildConfigureCommandMethodForStreamState(EventGraph graph, GeneratedType streamQueryHandlerType) { var sql = $"select id, version, type, timestamp, created as timestamp, is_archived from {graph.DatabaseSchemaName}.mt_streams where id = ?"; if (graph.TenancyStyle == TenancyStyle.Conjoined) { streamQueryHandlerType.AllInjectedFields.Add(new InjectedField(typeof(string), "tenantId")); sql += $" and {TenantIdColumn.Name} = ?"; } var configureCommand = streamQueryHandlerType.MethodFor("ConfigureCommand"); configureCommand.Frames.Call <CommandBuilder>(x => x.AppendWithParameters(""), @call => { @call.Arguments[0] = Constant.ForString(sql); @call.ReturnAction = ReturnAction.Initialize; }); var idDbType = graph.StreamIdentity == StreamIdentity.AsGuid ? DbType.Guid : DbType.String; configureCommand.Frames.Code("{0}[0].Value = _streamId;", Use.Type <NpgsqlParameter[]>()); configureCommand.Frames.Code("{0}[0].DbType = {1};", Use.Type <NpgsqlParameter[]>(), idDbType); if (graph.TenancyStyle == TenancyStyle.Conjoined) { configureCommand.Frames.Code("{0}[1].Value = _tenantId;", Use.Type <NpgsqlParameter[]>()); configureCommand.Frames.Code("{0}[1].DbType = {1};", Use.Type <NpgsqlParameter[]>(), DbType.String); } }
public override void GenerateBulkWriterCodeAsync(GeneratedType type, GeneratedMethod load, DocumentMapping mapping) { load.Frames.CodeAsync($"await writer.WriteAsync(\"BULK_INSERT\", {{0}}, {{1}});", DbType, Use.Type <CancellationToken>()); }
public dependency_inlining() { theAssembly = new GeneratedAssembly(new GenerationRules("Lamar.Generated")); theType = theAssembly.AddType("GeneratedClass", typeof(Message1Handler)); theMethod = theType.MethodFor("Handle"); }