Эх сурвалжийг харах

Custom Ninject based command handler wrapper

Lukas Angerer 4 жил өмнө
parent
commit
130639b25e

+ 27 - 0
CustomHostingDemo/CustomCommand.cs

@@ -0,0 +1,27 @@
+using Ninject;
+using System;
+using System.CommandLine;
+
+namespace CustomHostingDemo
+{
+    public class CustomCommand<TArg> : Command
+    {
+        private readonly Type _handlerType;
+
+        public CustomCommand(string name, string description, Type handler)
+            : base(name, description)
+        {
+            _handlerType = handler;
+        }
+
+        public Command Bind(IKernel kernel)
+        {
+            kernel.Bind<TArg>().ToSelf().InTransientScope();
+            kernel.Bind(_handlerType).ToSelf().InTransientScope();
+
+            Handler = new NinjectCommandHandler<TArg>(kernel, _handlerType);
+
+            return this;
+        }
+    }
+}

+ 14 - 17
CustomHostingDemo/HelloCommand.cs

@@ -1,21 +1,18 @@
-using Ninject.Syntax;
+using Microsoft.Extensions.Logging;
 using System;
-using System.Collections.Generic;
 using System.CommandLine;
 using System.CommandLine.Invocation;
 using System.CommandLine.IO;
-using System.Linq;
-using System.Text;
+using System.CommandLine.Rendering;
 using System.Threading.Tasks;
 
 namespace CustomHostingDemo
 {
-    public class HelloCommand : Command
+    public class HelloCommand : CustomCommand<HelloCommand.HelloArgs>
     {
         public HelloCommand()
-            : base("hello", "says hello")
+            : base("hello", "says hello", typeof(DefaultHandler))
         {
-            Handler = CommandHandler.Create(typeof(DefaultHandler).GetMethod(nameof(ICommandHandler.InvokeAsync)));
             AddArgument(new Argument<DateTime>("date", () => DateTime.Today));
             AddOption(new Option<bool>("--verbose"));
         }
@@ -26,24 +23,24 @@ namespace CustomHostingDemo
             public bool Verbose { get; set; }
         }
 
-        public class DefaultHandler : ICommandHandler
+        public class DefaultHandler : ICommandHandler<HelloArgs>
         {
-            private readonly HelloArgs _args;
-            private readonly IResolutionRoot _resolutionRoot;
+            private readonly ILogger _logger;
 
-            public DefaultHandler(HelloArgs args, IResolutionRoot resolutionRoot)
+            public DefaultHandler(Logger<DefaultHandler> logger)
             {
-                _args = args;
-                _resolutionRoot = resolutionRoot;
+                _logger = logger;
             }
 
-            public Task<int> InvokeAsync(InvocationContext context)
+            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}");
+                context.Console.Out.WriteLine($"P: --date {args.Date}");
+                context.Console.Out.WriteLine($"P: --verbose {args.Verbose}");
 
-                return Task.FromResult(0);
+                _logger.LogInformation("INFO from DefaultHandler");
+
+                return Task.FromResult(3);
             }
         }
     }

+ 40 - 0
CustomHostingDemo/NinjectCommandHandler.cs

@@ -0,0 +1,40 @@
+using Ninject;
+using System;
+using System.CommandLine.Binding;
+using System.CommandLine.Invocation;
+using System.Threading.Tasks;
+
+namespace CustomHostingDemo
+{
+    public interface ICommandHandler<TArg>
+    {
+        Task<int> InvokeAsync(InvocationContext context, TArg args);
+    }
+
+    public class NinjectCommandHandler<TArg> : ICommandHandler
+    {
+        private readonly IKernel _kernel;
+        private readonly Type _handlerType;
+
+        public NinjectCommandHandler(IKernel kernel, Type handlerType)
+        {
+            _kernel = kernel;
+            _handlerType = handlerType;
+
+            if (!typeof(ICommandHandler<TArg>).IsAssignableFrom(_handlerType))
+            {
+                throw new ArgumentException($"The handler type must implement ICommandHandler<{typeof(TArg).Name}>", nameof(handlerType));
+            }
+        }
+
+        public Task<int> InvokeAsync(InvocationContext context)
+        {
+            var cmdArgs = _kernel.Get<TArg>();
+            var binder = new ModelBinder<TArg>();
+            binder.UpdateInstance(cmdArgs, context.BindingContext);
+
+            var handler = (ICommandHandler<TArg>)_kernel.Get(_handlerType);
+            return handler.InvokeAsync(context, cmdArgs);
+        }
+    }
+}

+ 16 - 16
CustomHostingDemo/Program.cs

@@ -15,7 +15,7 @@ namespace CustomHostingDemo
 {
     class Program
     {
-        static void Main(string[] args)
+        static int Main(string[] args)
         {
             var kernel = new StandardKernel();
 
@@ -38,29 +38,29 @@ namespace CustomHostingDemo
 
             var rootCommand = new RootCommand()
             {
-                new HelloCommand(),
+                new HelloCommand().Bind(kernel),
             };
 
             var parser = new CommandLineBuilder(rootCommand)
-                .UseMiddleware((invocationContext) =>
-                {
-                    var cmdArgs = new HelloCommand.HelloArgs();
-                    var binder = new ModelBinder<HelloCommand.HelloArgs>();
-                    binder.UpdateInstance(cmdArgs, invocationContext.BindingContext);
+                //.UseMiddleware((invocationContext) =>
+                //{
+                //    var cmdArgs = new HelloCommand.HelloArgs();
+                //    var binder = new ModelBinder<HelloCommand.HelloArgs>();
+                //    binder.UpdateInstance(cmdArgs, invocationContext.BindingContext);
 
-                    kernel.Bind<HelloCommand.HelloArgs>().ToConstant(cmdArgs).InSingletonScope();
+                //    kernel.Bind<HelloCommand.HelloArgs>().ToConstant(cmdArgs).InSingletonScope();
 
-                    //invocationContext.BindingContext.AddService(typeof(HelloCommand.HelloArgs), () => cmdArgs);
-                    invocationContext.BindingContext.AddService(typeof(HelloCommand.DefaultHandler), () =>
-                    {
-                        var handler = kernel.Get<HelloCommand.DefaultHandler>();
-                        return handler;
-                    });
-                })
+                //    //invocationContext.BindingContext.AddService(typeof(HelloCommand.HelloArgs), () => cmdArgs);
+                //    invocationContext.BindingContext.AddService(typeof(HelloCommand.DefaultHandler), () =>
+                //    {
+                //        var handler = kernel.Get<HelloCommand.DefaultHandler>();
+                //        return handler;
+                //    });
+                //})
                 .UseDefaults()
                 .Build();
 
-            parser.InvokeAsync(args).Wait();
+            return parser.InvokeAsync(args).Result;
         }
     }
 }