Mejores prácticas de inicio de sesión de WinForm

Aug 17 2020

Tengo un inicio de sesión de trabajo para un proyecto de WinForms. Utilizo el program.csarchivo para iniciar el formulario de inicio de sesión. No estoy tan seguro de que no haya una mejor manera de implementar esto.

Aquí está mi archivo program.cs:

    using System;
    using System.Windows.Forms;
    using WindowsFormsApp.Presenters;
    using WindowsFormsApp.Views;
    using Autofac;
    using DbContexts;
    using Serilog;

    namespace WindowsFormsApp
    {
        internal static class Program
        {
            public static IContainer Container { get; private set; }
            public static string UserName { get; set; }

            /// <summary>
            /// The main entry point for the application.
            /// </summary>
            [STAThread]
            private static void Main()
            {
                var builder = new ContainerBuilder();

                builder.Register(c => new MyContext());
            
                Container = builder.Build();

                Log.Logger = new LoggerConfiguration()
                    .MinimumLevel.Debug()
                    .WriteTo.Console()
                    .WriteTo.RollingFile("log-{Date}.txt")
                    .CreateLogger();
                Log.Information("Application Started");

                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);

                var loginForm = new LoginForm();
                var results = loginForm.ShowDialog();

                if (results == DialogResult.Cancel)
                    System.Environment.Exit(1);

                while (results != DialogResult.OK)
                {
                    results = loginForm.ShowDialog();
                    if (results == DialogResult.Cancel)
                        System.Environment.Exit(1);
                }

                var mainFormView = new MainFormView();

                mainFormView.Tag = new MainFormPresenter(mainFormView);

                Application.Run(mainFormView);
            }
        }
    }

Cualquier sugerencia o comentario es bienvenido.

Respuestas

4 MartinVerjans Aug 17 2020 at 16:18
  1. Tiene una propiedad estática pública UserName que cualquiera puede configurar, en cualquier lugar de su código. No detalló el uso de esta propiedad.
  • Si es el formulario de inicio de sesión el que debería actualizarlo y nunca más se actualizará, haga que su clase de programa configure este campo.

  • Si es otra clase la que actualiza este campo, tal vez esta propiedad no pertenezca aquí.

  1. Tiene algún código que está duplicado, por lo que debe haber una manera de hacerlo mejor.

  2. Desde mi punto de vista, está haciendo muchas cosas diferentes en su método principal, tal vez podría poner estas operaciones en métodos separados: Init, Login, Start.

  3. usar usando

  4. Pones el Presentador para MainForm en la propiedad de la etiqueta, que creo que pertenece a una propiedad específica. De esa manera, MainForm puede controlar quién tiene acceso a él; de lo contrario, cualquier objeto que tenga acceso a MainForm puede recuperar la etiqueta y, por lo tanto, el presentador. Otro problema es que la propiedad Tag es un objeto, por lo que tendrás que convertirla cada vez que quieras usarla.

Entonces, todo junto se convertiría en:

using System;
using System.Windows.Forms;
using WindowsFormsApp.Presenters;
using WindowsFormsApp.Views;
using Autofac;
using DbContexts;
using Serilog;

namespace WindowsFormsApp
{
    internal static class Program
    {
        public static IContainer Container { get; private set; }
        public static string UserName { get; private set; }

        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        private static void Main()
        {
            Init();
            Login();
            Start();
        }

        private void Init()
        {
            var builder = new ContainerBuilder();
            builder.Register(c => new MyContext());            
            Container = builder.Build();

            Log.Logger = new LoggerConfiguration()
                .MinimumLevel.Debug()
                .WriteTo.Console()
                .WriteTo.RollingFile("log-{Date}.txt")
                .CreateLogger();
            Log.Information("Application Started");

            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
        }

        private void Login()
        {
            using (loginForm = new LoginForm())
            {
                var results DialogResult.None;
                do
                {
                    results = loginForm.ShowDialog();
                    if (results == DialogResult.Cancel)
                        System.Environment.Exit(1);
                } while (results != DialogResult.OK);
                //Since we logged on correctly, we can update UserName (I guess)
                UserName = loginForm.ValidatedUserName;
            }
        }
 
        private void Start()
        {
            using (var mainFormView = new MainFormView())
            {
                mainFormView.Presenter = new MainFormPresenter(mainFormView);
                Application.Run(mainFormView);
            }
        }
    }
}
2 tinstaafl Aug 17 2020 at 06:45

Lo primero que noté. Duplicación de código. Cada vez que vea esto, su primer pensamiento debería ser: "Tiene que haber una mejor manera".

En este caso, asigne la variable de resultado para DialogResult.Noneluego mostrar el cuadro de diálogo dentro del ciclo:

var result = DialogResult.None;
while(result != DialogResult.OK)
{
    result = loginForm.ShowDialog();
    if(result == DialogResult.Cancel)
    {
        System.Environment.Exit(1);
    }
}