Рекомендации по входу в WinForm

Aug 17 2020

У меня есть рабочий вход в проект WinForms. Я использую program.csфайл для запуска формы входа. Я не уверен, что нет лучшего способа реализовать это.

Вот мой файл 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);
            }
        }
    }

Любые предложения или комментарии приветствуются.

Ответы

4 MartinVerjans Aug 17 2020 at 16:18
  1. У вас есть общедоступное статическое свойство UserName, которое может быть установлено кем угодно в любом месте вашего кода. Вы не указали подробности использования этого свойства.
  • Если это форма входа в систему, которая должна его обновить и никогда не будет обновляться снова, пусть ваш класс Program установит это поле.

  • Если это поле обновляет другой класс, возможно, это свойство здесь не принадлежит.

  1. У вас есть дублированный код, поэтому должен быть способ улучшить его.

  2. С моей точки зрения, вы делаете много разных вещей в своем методе Main, возможно, вы могли бы поместить эти операции в отдельные методы: Init, Login, Start.

  3. Используйте с помощью

  4. Вы помещаете Presenter для MainForm в свойство Tag, которое, как мне кажется, принадлежит определенному свойству. Таким образом, MainForm может контролировать, кто имеет к нему доступ, в противном случае любой объект, имеющий доступ к MainForm, может восстановить тег и, следовательно, Presenter. Другая проблема заключается в том, что свойство Tag является объектом, поэтому вам придется преобразовывать его каждый раз, когда вы хотите его использовать.

Итак, все вместе это станет:

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

Первое, что заметил. Дублирование кода. Всякий раз, когда вы видите это, вашей первой мыслью должно быть: «Должен быть способ лучше».

В этом случае назначьте переменную результата, чтобы DialogResult.Noneпросто показать диалог внутри цикла:

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