Meilleures pratiques de connexion WinForm
J'ai une connexion de travail pour un projet WinForms. J'utilise le program.cs
fichier pour lancer le formulaire de connexion. Je ne suis pas sûr qu'il n'y ait pas une meilleure façon de mettre cela en œuvre.
Voici mon fichier 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);
}
}
}
Toutes suggestions ou commentaires sont les bienvenus.
Réponses
- Vous avez une propriété statique publique UserName qui peut être définie par n'importe qui, n'importe où dans votre code. Vous n'avez pas détaillé l'utilisation de cette propriété.
Si c'est le formulaire de connexion qui doit le mettre à jour et qu'il ne sera plus jamais mis à jour, demandez à votre classe Program de définir ce champ.
Si c'est une autre classe qui met à jour ce champ, peut-être que cette propriété n'a pas sa place ici.
Vous avez du code qui est dupliqué, il doit donc y avoir un moyen de faire mieux.
De mon point de vue, vous faites beaucoup de choses différentes dans votre méthode Main, peut-être pourriez-vous mettre ces opérations dans des méthodes distinctes : Init, Login, Start.
Utiliser en utilisant
Vous placez le présentateur pour MainForm dans la propriété Tag, qui, je pense, appartient à une propriété spécifique. De cette façon, le MainForm peut contrôler qui y a accès, sinon tout objet ayant accès au MainForm peut récupérer le Tag et donc le Presenter. Un autre problème est que la propriété Tag est un objet, vous devrez donc la convertir à chaque fois que vous voudrez l'utiliser.
Donc, tout cela deviendrait :
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);
}
}
}
}
La première chose que j'ai remarquée. Duplication de code. Chaque fois que vous voyez cela, votre première pensée devrait être "Il doit y avoir une meilleure façon.".
Dans ce cas, affectez la variable de résultat pour DialogResult.None
afficher simplement la boîte de dialogue à l'intérieur de la boucle :
var result = DialogResult.None;
while(result != DialogResult.OK)
{
result = loginForm.ShowDialog();
if(result == DialogResult.Cancel)
{
System.Environment.Exit(1);
}
}