Просмотр исходного кода

Injecting invocation context with dynamic factory

Lukas Angerer 4 лет назад
Родитель
Сommit
6b78005416

+ 6 - 4
CustomHostingDemo/HelloCommand.cs

@@ -26,17 +26,19 @@ namespace CustomHostingDemo
         public class DefaultHandler : ICommandHandler<HelloArgs>
         {
             private readonly ILogger _logger;
+            private readonly ILog _log;
 
-            public DefaultHandler(Logger<DefaultHandler> logger)
+            public DefaultHandler(Logger<DefaultHandler> logger, ILog log)
             {
                 _logger = logger;
+                _log = log;
             }
 
             public Task<int> InvokeAsync(InvocationContext context, HelloArgs args)
             {
-                context.Console.Out.WriteLine("Hello YOU!");
-                context.Console.Out.WriteLine($"P: --date {args.Date}");
-                context.Console.Out.WriteLine($"P: --verbose {args.Verbose}");
+                _log.LogMessage("Hello YOU!");
+                _log.LogMessage($"P: --date {args.Date}");
+                _log.LogMessage($"P: --verbose {args.Verbose}");
 
                 _logger.LogInformation("INFO from DefaultHandler");
 

+ 36 - 0
CustomHostingDemo/ILog.cs

@@ -0,0 +1,36 @@
+using System;
+using System.Collections.Generic;
+using System.CommandLine;
+using System.CommandLine.Invocation;
+using System.CommandLine.IO;
+using System.CommandLine.Rendering;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CustomHostingDemo
+{
+    public interface ILog
+    {
+        void LogMessage(string msg);
+    }
+
+    public class Log : ILog
+    {
+        private readonly IConsole _console;
+
+        public Log(InvocationContext context)
+        {
+            _console = context.Console;
+        }
+
+        public void LogMessage(string msg)
+        {
+            _console.Out.WriteLine(new ContainerSpan(
+                ForegroundColorSpan.LightBlue(),
+                new ContentSpan(msg),
+                ForegroundColorSpan.Reset()
+            ).ToString(OutputMode.Ansi));
+        }
+    }
+}

+ 2 - 1
CustomHostingDemo/NinjectCommandHandler.cs

@@ -1,4 +1,5 @@
 using Ninject;
+using Ninject.Parameters;
 using System;
 using System.CommandLine.Binding;
 using System.CommandLine.Invocation;
@@ -33,7 +34,7 @@ namespace CustomHostingDemo
             var binder = new ModelBinder<TArg>();
             binder.UpdateInstance(cmdArgs, context.BindingContext);
 
-            var handler = (ICommandHandler<TArg>)_kernel.Get(_handlerType);
+            var handler = (ICommandHandler<TArg>)_kernel.Get(_handlerType, new Parameter(nameof(InvocationContext), context, shouldInherit: true));
             return handler.InvokeAsync(context, cmdArgs);
         }
     }

+ 14 - 0
CustomHostingDemo/Program.cs

@@ -7,8 +7,10 @@ using System;
 using System.CommandLine;
 using System.CommandLine.Binding;
 using System.CommandLine.Builder;
+using System.CommandLine.Invocation;
 using System.CommandLine.Parsing;
 using System.IO;
+using System.Linq;
 using System.Reflection;
 
 namespace CustomHostingDemo
@@ -29,6 +31,18 @@ namespace CustomHostingDemo
             kernel.Bind<ILoggerFactory>().To<LoggerFactory>().InSingletonScope();
             kernel.Bind(typeof(Logger<>)).ToSelf().InSingletonScope();
             kernel.Bind<ILoggerProvider>().To<LoggerProvider>().InSingletonScope();
+            kernel.Bind<ILog>().To<Log>().InTransientScope();
+
+            kernel.Bind<InvocationContext>().ToMethod(ctx =>
+            {
+                var parameter = ctx.Parameters.FirstOrDefault(p => p.Name == nameof(InvocationContext));
+                if (parameter == null)
+                {
+                    throw new Exception("Cannot resolve InvocationContext outside of an actual NinjectCommandHandler invocation");
+                }
+
+                return (InvocationContext)parameter.GetValue(ctx, null);
+            });
 
             Console.WriteLine($"Hello {config["Hello"]}");