public InvocationInfo(OnceInterceptor interceptor, string id, IInvocation invocation) { this.interceptor = interceptor; this.invocation = invocation; this.Id = id; Logger.Information("Begin {id}", Id); Begin = DateTime.UtcNow; invocation.Proceed(); if (ReturnValue is Task task) { var returnType = task.GetType(); if (returnType.IsGenericType) { var resultHandlerType = typeof(TaskResultHandler <>) .MakeGenericType(returnType.GetGenericArguments()[0]); var resultHandler = (IReturnValueSource)Activator.CreateInstance(resultHandlerType, this, task); invocation.ReturnValue = resultHandler.ReturnValue; } else { var handler = new TaskHandler(this, task); invocation.ReturnValue = handler.ReturnValue; } } else { invocation.ReturnValue = InterceptReturnValue(invocation.ReturnValue); Complete(); } }
/// <summary> /// Creates an instance of T where all methods marked with [Once] are only executed once. /// </summary> /// <typeparam name="T"></typeparam> /// <returns></returns> public static T Once <T>(Action <T> initializer) { var builder = new DefaultProxyBuilder(); var generator = new ProxyGenerator(builder); var onceInterceptor = new OnceInterceptor(); var onceProxy = generator.CreateClassProxy(typeof(T), new ProxyGenerationOptions { Hook = new OnceHook() }, onceInterceptor); var proxy = (T)onceProxy; initializer(proxy); return(proxy); }
public OnceInterceptor(OnceInterceptor parent, string prefix) { this.prefix = prefix; _cache = parent._cache; }
public ExitCode Run() { try { Logger = Log.Logger = new LoggerConfiguration() .WriteTo.Console(SerilogLogEventLevel(Verbosity.Detailed)) .CreateLogger(); var builder = new DefaultProxyBuilder(); var generator = new ProxyGenerator(builder); var onceInterceptor = new OnceInterceptor(); var onceProxy = generator.CreateClassProxy(targetsType, new ProxyGenerationOptions { Hook = new OnceHook() }, onceInterceptor); var options = new Options(onceProxy); GetOptParser.Parse(commandLineArguments, options); if (rebuildCheck) { if (IsOutOfDate() && !options.IgnoreClean) { return(RequireRebuild()); } } Logger = Log.Logger = new LoggerConfiguration() .WriteTo.Console(SerilogLogEventLevel(options.Verbosity), outputTemplate: "{Timestamp:o}|{Level:u3}|{Message:lj}{NewLine}{Exception}") .CreateLogger(); if (options.Edit) { var cmd = new Tool("cmd").WithArguments("/c", "start"); var buildCsProj = sourceDir.Glob("*.csproj").First(); cmd.Run(buildCsProj).Wait(); return(ExitCode.HelpDisplayed); } if ((options.Clean && !options.IgnoreClean)) { return(RequireRebuild()); } if (options.Help) { HelpText.Print(Console.Out, options); return(ExitCode.HelpDisplayed); } var(target, targetArguments) = ParseCommandLineTarget(commandLineArguments, options); var amgBuildAssembly = Assembly.GetExecutingAssembly(); Logger.Information("Amg.Build: {assembly} {build}", amgBuildAssembly.Location, amgBuildAssembly.GetCustomAttribute <AssemblyInformationalVersionAttribute>().InformationalVersion); var startup = GetStartupInvocation(); IEnumerable <InvocationInfo> invocations = new[] { startup }; try { RunTarget(options.Targets, target, targetArguments); } catch (InvocationFailed) { invocations = invocations.Concat(onceInterceptor.Invocations); if (options.Verbosity > Verbosity.Quiet) { Console.WriteLine(Summary.Print(invocations)); } Console.Error.WriteLine(Summary.Error(invocations)); return(ExitCode.TargetFailed); } invocations = invocations.Concat(onceInterceptor.Invocations); if (options.Verbosity > Verbosity.Quiet) { Console.WriteLine(Summary.Print(invocations)); } return(ExitCode.Success); } catch (ParseException ex) { Console.Error.WriteLine(ex.Message); Console.Error.WriteLine(); Console.Error.WriteLine("Run with --help to get help."); return(ExitCode.CommandLineError); } catch (Exception ex) { Console.Error.WriteLine(ex.Message); return(ExitCode.UnknownError); } }