public class Presenter { private readonly IView _view; private readonly IService _service; public Presenter(IView view, IService service) { _view = view; _service = service; _view.UserIdChanged += () => UpdateUserInfo(); } private void UpdateUserInfo() { var user = _service.GetUser(_view.UserId); _view.Username = user.Username; _view.Age = user.Age; } }
private static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new MainForm()); // () }
private static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); var presenter = new LoginPresenter(new LoginForm(), new LoginService()); // Dependency Injection presenter.Run(); }
// public interface IView { void Show(); void Close(); } // , public interface ILoginView : IView { string Username { get; } string Password { get; } event Action Login; // " " void ShowError(string errorMessage); } public interface IPresenter { void Run(); } // public interface ILoginService { bool Login(User user); // true - , false }
public class LoginPresenter : IPresenter { private readonly ILoginView _view; private readonly ILoginService _service; public LoginPresenter(ILoginView view, ILoginService service) { _view = view; _service = service; _view.Login += () => Login(_view.Username, _view.Password); } public void Run() { _view.Show(); } private void Login(string username, string password) { if (username == null) throw new ArgumentNullException("username"); if (password == null) throw new ArgumentNullException("password"); var user = new User {Name = username, Password = password}; if (!_service.Login(user)) { _view.ShowError("Invalid username or password"); } else { // , (?) } } }
public partial class LoginForm : Form, ILoginView { // ... public new void Show() { Application.Run(this); } }
[TestFixture] public class LoginPresenterTests { private ILoginView _view; [SetUp] public void SetUp() { _view = Substitute.For<ILoginView>(); // var service = Substitute.For<ILoginService>(); // service.Login(Arg.Any<User>()) // admin/password .Returns(info => info.Arg<User>().Name == "admin" && info.Arg<User>().Password == "password"); var presenter = new LoginPresenter(_view, service); presenter.Run(); } [Test] public void InvalidUser() { _view.Username.Returns("Vladimir"); _view.Password.Returns("VladimirPass"); _view.Login += Raise.Event<Action>(); _view.Received().ShowError(Arg.Any<string>()); // } [Test] public void ValidUser() { _view.Username.Returns("admin"); _view.Password.Returns("password"); _view.Login += Raise.Event<Action>(); _view.DidNotReceive().ShowError(Arg.Any<string>()); // } }
// LoginPresenter: var mainPresenter = new MainPresenter(new MainForm()); mainPresenter.Run(user);
public interface IApplicationController { IApplicationController RegisterView<TView, TImplementation>() where TImplementation : class, TView where TView : IView; IApplicationController RegisterService<TService, TImplementation>() where TImplementation : class, TService; void Run<TPresenter>() where TPresenter : class, IPresenter; }
private static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); // : var controller = new ApplicationController(new LightInjectAdapder()) .RegisterView<ILoginView, LoginForm>() .RegisterService<ILoginService, StupidLoginService>() .RegisterView<IMainView, MainForm>(); controller.Run<LoginPresenter>(); }
new ApplicationController(new LightInjectAdapder())
. As an IoC container, I used the LightInject library, but not directly, but through an adapter (Adapter pattern), so that if I need to change the container to another, I could write another adapter and not change the controller logic. All the methods used are in most IoC libraries, difficulties should not arise. IPresenter, , Run . .
, , , :
Controller.Run<MainPresener, User>(user); View.Close();
...
View.Close()
, , . , Application.Run(Form)
Windows . , ExitThread
Form.Closed
, .
, - : Application.Run(ApplicationContext)
, ApplicationContext.MainForm
. , (instance) ApplicationContext ( DI) . :
// LoginForm public new void Show() { _context.MainForm = this; Application.Run(_context); } // MainForm public new void Show() { _context.MainForm = this; base.Show(); }
. " " Controller.Run<ChangeUsernamePresenter, User>(user)
. - , ApplicationContext:
public new void Show() { ShowDialog(); }
, , Form.
... ?
, , :
, ( ). , , - . [] , , . [] . .
IoC- IContainer -.
c Github ( Nuget-).
, , - MVP, , , .
. , , !
, :
- ( );
- ( Event Aggregator);
-
,
, MVP
Passive View
Application Controller
Application Controller Event Aggregator
Application Controller
MVP ,
Presenter
IPresenter, , Run . .
, , , :
Controller.Run<MainPresener, User>(user); View.Close();
...
View.Close()
, , . , Application.Run(Form)
Windows . , ExitThread
Form.Closed
, .
, - : Application.Run(ApplicationContext)
, ApplicationContext.MainForm
. , (instance) ApplicationContext ( DI) . :
// LoginForm public new void Show() { _context.MainForm = this; Application.Run(_context); } // MainForm public new void Show() { _context.MainForm = this; base.Show(); }
. " " Controller.Run<ChangeUsernamePresenter, User>(user)
. - , ApplicationContext:
public new void Show() { ShowDialog(); }
, , Form.
... ?
, , :
, ( ). , , - . [] , , . [] . .
IoC- IContainer -.
c Github ( Nuget-).
, , - MVP, , , .
. , , !
, :
- ( );
- ( Event Aggregator);
-
,
, MVP
Passive View
Application Controller
Application Controller Event Aggregator
Application Controller
MVP ,
Presenter
IPresenter, , Run . .
, , , :
Controller.Run<MainPresener, User>(user); View.Close();
...
View.Close()
, , . , Application.Run(Form)
Windows . , ExitThread
Form.Closed
, .
, - : Application.Run(ApplicationContext)
, ApplicationContext.MainForm
. , (instance) ApplicationContext ( DI) . :
// LoginForm public new void Show() { _context.MainForm = this; Application.Run(_context); } // MainForm public new void Show() { _context.MainForm = this; base.Show(); }
. " " Controller.Run<ChangeUsernamePresenter, User>(user)
. - , ApplicationContext:
public new void Show() { ShowDialog(); }
, , Form.
... ?
, , :
, ( ). , , - . [] , , . [] . .
IoC- IContainer -.
c Github ( Nuget-).
, , - MVP, , , .
. , , !
, :
- ( );
- ( Event Aggregator);
-
,
, MVP
Passive View
Application Controller
Application Controller Event Aggregator
Application Controller
MVP ,
Presenter
IPresenter, , Run . .
, , , :
Controller.Run<MainPresener, User>(user); View.Close();
...
View.Close()
, , . , Application.Run(Form)
Windows . , ExitThread
Form.Closed
, .
, - : Application.Run(ApplicationContext)
, ApplicationContext.MainForm
. , (instance) ApplicationContext ( DI) . :
// LoginForm public new void Show() { _context.MainForm = this; Application.Run(_context); } // MainForm public new void Show() { _context.MainForm = this; base.Show(); }
. " " Controller.Run<ChangeUsernamePresenter, User>(user)
. - , ApplicationContext:
public new void Show() { ShowDialog(); }
, , Form.
... ?
, , :
, ( ). , , - . [] , , . [] . .
IoC- IContainer -.
c Github ( Nuget-).
, , - MVP, , , .
. , , !
, :
- ( );
- ( Event Aggregator);
-
,
, MVP
Passive View
Application Controller
Application Controller Event Aggregator
Application Controller
MVP ,
Presenter
IPresenter, , Run . .
, , , :
Controller.Run<MainPresener, User>(user); View.Close();
...
View.Close()
, , . , Application.Run(Form)
Windows . , ExitThread
Form.Closed
, .
, - : Application.Run(ApplicationContext)
, ApplicationContext.MainForm
. , (instance) ApplicationContext ( DI) . :
// LoginForm public new void Show() { _context.MainForm = this; Application.Run(_context); } // MainForm public new void Show() { _context.MainForm = this; base.Show(); }
. " " Controller.Run<ChangeUsernamePresenter, User>(user)
. - , ApplicationContext:
public new void Show() { ShowDialog(); }
, , Form.
... ?
, , :
, ( ). , , - . [] , , . [] . .
IoC- IContainer -.
c Github ( Nuget-).
, , - MVP, , , .
. , , !
, :
- ( );
- ( Event Aggregator);
-
,
, MVP
Passive View
Application Controller
Application Controller Event Aggregator
Application Controller
MVP ,
Presenter
IPresenter, , Run . .
, , , :
Controller.Run<MainPresener, User>(user); View.Close();
...
View.Close()
, , . , Application.Run(Form)
Windows . , ExitThread
Form.Closed
, .
, - : Application.Run(ApplicationContext)
, ApplicationContext.MainForm
. , (instance) ApplicationContext ( DI) . :
// LoginForm public new void Show() { _context.MainForm = this; Application.Run(_context); } // MainForm public new void Show() { _context.MainForm = this; base.Show(); }
. " " Controller.Run<ChangeUsernamePresenter, User>(user)
. - , ApplicationContext:
public new void Show() { ShowDialog(); }
, , Form.
... ?
, , :
, ( ). , , - . [] , , . [] . .
IoC- IContainer -.
c Github ( Nuget-).
, , - MVP, , , .
. , , !
, :
- ( );
- ( Event Aggregator);
-
,
, MVP
Passive View
Application Controller
Application Controller Event Aggregator
Application Controller
MVP ,
Presenter
IPresenter, , Run . .
, , , :
Controller.Run<MainPresener, User>(user); View.Close();
...
View.Close()
, , . , Application.Run(Form)
Windows . , ExitThread
Form.Closed
, .
, - : Application.Run(ApplicationContext)
, ApplicationContext.MainForm
. , (instance) ApplicationContext ( DI) . :
// LoginForm public new void Show() { _context.MainForm = this; Application.Run(_context); } // MainForm public new void Show() { _context.MainForm = this; base.Show(); }
. " " Controller.Run<ChangeUsernamePresenter, User>(user)
. - , ApplicationContext:
public new void Show() { ShowDialog(); }
, , Form.
... ?
, , :
, ( ). , , - . [] , , . [] . .
IoC- IContainer -.
c Github ( Nuget-).
, , - MVP, , , .
. , , !
, :
- ( );
- ( Event Aggregator);
-
,
, MVP
Passive View
Application Controller
Application Controller Event Aggregator
Application Controller
MVP ,
Presenter
IPresenter, , Run . .
, , , :
Controller.Run<MainPresener, User>(user); View.Close();
...
View.Close()
, , . , Application.Run(Form)
Windows . , ExitThread
Form.Closed
, .
, - : Application.Run(ApplicationContext)
, ApplicationContext.MainForm
. , (instance) ApplicationContext ( DI) . :
// LoginForm public new void Show() { _context.MainForm = this; Application.Run(_context); } // MainForm public new void Show() { _context.MainForm = this; base.Show(); }
. " " Controller.Run<ChangeUsernamePresenter, User>(user)
. - , ApplicationContext:
public new void Show() { ShowDialog(); }
, , Form.
... ?
, , :
, ( ). , , - . [] , , . [] . .
IoC- IContainer -.
c Github ( Nuget-).
, , - MVP, , , .
. , , !
, :
- ( );
- ( Event Aggregator);
-
,
, MVP
Passive View
Application Controller
Application Controller Event Aggregator
Application Controller
MVP ,
Presenter
IPresenter, , Run . .
, , , :
Controller.Run<MainPresener, User>(user); View.Close();
...
View.Close()
, , . , Application.Run(Form)
Windows . , ExitThread
Form.Closed
, .
, - : Application.Run(ApplicationContext)
, ApplicationContext.MainForm
. , (instance) ApplicationContext ( DI) . :
// LoginForm public new void Show() { _context.MainForm = this; Application.Run(_context); } // MainForm public new void Show() { _context.MainForm = this; base.Show(); }
. " " Controller.Run<ChangeUsernamePresenter, User>(user)
. - , ApplicationContext:
public new void Show() { ShowDialog(); }
, , Form.
... ?
, , :
, ( ). , , - . [] , , . [] . .
IoC- IContainer -.
c Github ( Nuget-).
, , - MVP, , , .
. , , !
, :
- ( );
- ( Event Aggregator);
-
,
, MVP
Passive View
Application Controller
Application Controller Event Aggregator
Application Controller
MVP ,
Presenter
IPresenter, , Run . .
, , , :
Controller.Run<MainPresener, User>(user); View.Close();
...
View.Close()
, , . , Application.Run(Form)
Windows . , ExitThread
Form.Closed
, .
, - : Application.Run(ApplicationContext)
, ApplicationContext.MainForm
. , (instance) ApplicationContext ( DI) . :
// LoginForm public new void Show() { _context.MainForm = this; Application.Run(_context); } // MainForm public new void Show() { _context.MainForm = this; base.Show(); }
. " " Controller.Run<ChangeUsernamePresenter, User>(user)
. - , ApplicationContext:
public new void Show() { ShowDialog(); }
, , Form.
... ?
, , :
, ( ). , , - . [] , , . [] . .
IoC- IContainer -.
c Github ( Nuget-).
, , - MVP, , , .
. , , !
, :
- ( );
- ( Event Aggregator);
-
,
, MVP
Passive View
Application Controller
Application Controller Event Aggregator
Application Controller
MVP ,
Presenter
IPresenter, , Run . .
, , , :
Controller.Run<MainPresener, User>(user); View.Close();
...
View.Close()
, , . , Application.Run(Form)
Windows . , ExitThread
Form.Closed
, .
, - : Application.Run(ApplicationContext)
, ApplicationContext.MainForm
. , (instance) ApplicationContext ( DI) . :
// LoginForm public new void Show() { _context.MainForm = this; Application.Run(_context); } // MainForm public new void Show() { _context.MainForm = this; base.Show(); }
. " " Controller.Run<ChangeUsernamePresenter, User>(user)
. - , ApplicationContext:
public new void Show() { ShowDialog(); }
, , Form.
... ?
, , :
, ( ). , , - . [] , , . [] . .
IoC- IContainer -.
c Github ( Nuget-).
, , - MVP, , , .
. , , !
, :
- ( );
- ( Event Aggregator);
-
,
, MVP
Passive View
Application Controller
Application Controller Event Aggregator
Application Controller
MVP ,
Presenter
IPresenter, , Run . .
, , , :
Controller.Run<MainPresener, User>(user); View.Close();
...
View.Close()
, , . , Application.Run(Form)
Windows . , ExitThread
Form.Closed
, .
, - : Application.Run(ApplicationContext)
, ApplicationContext.MainForm
. , (instance) ApplicationContext ( DI) . :
// LoginForm public new void Show() { _context.MainForm = this; Application.Run(_context); } // MainForm public new void Show() { _context.MainForm = this; base.Show(); }
. " " Controller.Run<ChangeUsernamePresenter, User>(user)
. - , ApplicationContext:
public new void Show() { ShowDialog(); }
, , Form.
... ?
, , :
, ( ). , , - . [] , , . [] . .
IoC- IContainer -.
c Github ( Nuget-).
, , - MVP, , , .
. , , !
, :
- ( );
- ( Event Aggregator);
-
,
, MVP
Passive View
Application Controller
Application Controller Event Aggregator
Application Controller
MVP ,
Presenter
IPresenter, , Run . .
, , , :
Controller.Run<MainPresener, User>(user); View.Close();
...
View.Close()
, , . , Application.Run(Form)
Windows . , ExitThread
Form.Closed
, .
, - : Application.Run(ApplicationContext)
, ApplicationContext.MainForm
. , (instance) ApplicationContext ( DI) . :
// LoginForm public new void Show() { _context.MainForm = this; Application.Run(_context); } // MainForm public new void Show() { _context.MainForm = this; base.Show(); }
. " " Controller.Run<ChangeUsernamePresenter, User>(user)
. - , ApplicationContext:
public new void Show() { ShowDialog(); }
, , Form.
... ?
, , :
, ( ). , , - . [] , , . [] . .
IoC- IContainer -.
c Github ( Nuget-).
, , - MVP, , , .
. , , !
, :
- ( );
- ( Event Aggregator);
-
,
, MVP
Passive View
Application Controller
Application Controller Event Aggregator
Application Controller
MVP ,
Presenter
IPresenter, , Run . .
, , , :
Controller.Run<MainPresener, User>(user); View.Close();
...
View.Close()
, , . , Application.Run(Form)
Windows . , ExitThread
Form.Closed
, .
, - : Application.Run(ApplicationContext)
, ApplicationContext.MainForm
. , (instance) ApplicationContext ( DI) . :
// LoginForm public new void Show() { _context.MainForm = this; Application.Run(_context); } // MainForm public new void Show() { _context.MainForm = this; base.Show(); }
. " " Controller.Run<ChangeUsernamePresenter, User>(user)
. - , ApplicationContext:
public new void Show() { ShowDialog(); }
, , Form.
... ?
, , :
, ( ). , , - . [] , , . [] . .
IoC- IContainer -.
c Github ( Nuget-).
, , - MVP, , , .
. , , !
, :
- ( );
- ( Event Aggregator);
-
,
, MVP
Passive View
Application Controller
Application Controller Event Aggregator
Application Controller
MVP ,
Presenter
IPresenter, , Run . .
, , , :
Controller.Run<MainPresener, User>(user); View.Close();
...
View.Close()
, , . , Application.Run(Form)
Windows . , ExitThread
Form.Closed
, .
, - : Application.Run(ApplicationContext)
, ApplicationContext.MainForm
. , (instance) ApplicationContext ( DI) . :
// LoginForm public new void Show() { _context.MainForm = this; Application.Run(_context); } // MainForm public new void Show() { _context.MainForm = this; base.Show(); }
. " " Controller.Run<ChangeUsernamePresenter, User>(user)
. - , ApplicationContext:
public new void Show() { ShowDialog(); }
, , Form.
... ?
, , :
, ( ). , , - . [] , , . [] . .
IoC- IContainer -.
c Github ( Nuget-).
, , - MVP, , , .
. , , !
, :
- ( );
- ( Event Aggregator);
-
,
, MVP
Passive View
Application Controller
Application Controller Event Aggregator
Application Controller
MVP ,
Presenter
IPresenter, , Run . .
, , , :
Controller.Run<MainPresener, User>(user); View.Close();
...
View.Close()
, , . , Application.Run(Form)
Windows . , ExitThread
Form.Closed
, .
, - : Application.Run(ApplicationContext)
, ApplicationContext.MainForm
. , (instance) ApplicationContext ( DI) . :
// LoginForm public new void Show() { _context.MainForm = this; Application.Run(_context); } // MainForm public new void Show() { _context.MainForm = this; base.Show(); }
. " " Controller.Run<ChangeUsernamePresenter, User>(user)
. - , ApplicationContext:
public new void Show() { ShowDialog(); }
, , Form.
... ?
, , :
, ( ). , , - . [] , , . [] . .
IoC- IContainer -.
c Github ( Nuget-).
, , - MVP, , , .
. , , !
, :
- ( );
- ( Event Aggregator);
-
,
, MVP
Passive View
Application Controller
Application Controller Event Aggregator
Application Controller
MVP ,
Presenter
IPresenter, , Run . .
, , , :
Controller.Run<MainPresener, User>(user); View.Close();
...
View.Close()
, , . , Application.Run(Form)
Windows . , ExitThread
Form.Closed
, .
, - : Application.Run(ApplicationContext)
, ApplicationContext.MainForm
. , (instance) ApplicationContext ( DI) . :
// LoginForm public new void Show() { _context.MainForm = this; Application.Run(_context); } // MainForm public new void Show() { _context.MainForm = this; base.Show(); }
. " " Controller.Run<ChangeUsernamePresenter, User>(user)
. - , ApplicationContext:
public new void Show() { ShowDialog(); }
, , Form.
... ?
, , :
, ( ). , , - . [] , , . [] . .
IoC- IContainer -.
c Github ( Nuget-).
, , - MVP, , , .
. , , !
, :
- ( );
- ( Event Aggregator);
-
,
, MVP
Passive View
Application Controller
Application Controller Event Aggregator
Application Controller
MVP ,
Presenter
IPresenter, , Run . .
, , , :
Controller.Run<MainPresener, User>(user); View.Close();
...
View.Close()
, , . , Application.Run(Form)
Windows . , ExitThread
Form.Closed
, .
, - : Application.Run(ApplicationContext)
, ApplicationContext.MainForm
. , (instance) ApplicationContext ( DI) . :
// LoginForm public new void Show() { _context.MainForm = this; Application.Run(_context); } // MainForm public new void Show() { _context.MainForm = this; base.Show(); }
. " " Controller.Run<ChangeUsernamePresenter, User>(user)
. - , ApplicationContext:
public new void Show() { ShowDialog(); }
, , Form.
... ?
, , :
, ( ). , , - . [] , , . [] . .
IoC- IContainer -.
c Github ( Nuget-).
, , - MVP, , , .
. , , !
, :
- ( );
- ( Event Aggregator);
-
,
, MVP
Passive View
Application Controller
Application Controller Event Aggregator
Application Controller
MVP ,
Presenter
IPresenter, , Run . .
, , , :
Controller.Run<MainPresener, User>(user); View.Close();
...
View.Close()
, , . , Application.Run(Form)
Windows . , ExitThread
Form.Closed
, .
, - : Application.Run(ApplicationContext)
, ApplicationContext.MainForm
. , (instance) ApplicationContext ( DI) . :
// LoginForm public new void Show() { _context.MainForm = this; Application.Run(_context); } // MainForm public new void Show() { _context.MainForm = this; base.Show(); }
. " " Controller.Run<ChangeUsernamePresenter, User>(user)
. - , ApplicationContext:
public new void Show() { ShowDialog(); }
, , Form.
... ?
, , :
, ( ). , , - . [] , , . [] . .
IoC- IContainer -.
c Github ( Nuget-).
, , - MVP, , , .
. , , !
, :
- ( );
- ( Event Aggregator);
-
,
, MVP
Passive View
Application Controller
Application Controller Event Aggregator
Application Controller
MVP ,
Presenter
IPresenter, , Run . .
, , , :
Controller.Run<MainPresener, User>(user); View.Close();
...
View.Close()
, , . , Application.Run(Form)
Windows . , ExitThread
Form.Closed
, .
, - : Application.Run(ApplicationContext)
, ApplicationContext.MainForm
. , (instance) ApplicationContext ( DI) . :
// LoginForm public new void Show() { _context.MainForm = this; Application.Run(_context); } // MainForm public new void Show() { _context.MainForm = this; base.Show(); }
. " " Controller.Run<ChangeUsernamePresenter, User>(user)
. - , ApplicationContext:
public new void Show() { ShowDialog(); }
, , Form.
... ?
, , :
, ( ). , , - . [] , , . [] . .
IoC- IContainer -.
c Github ( Nuget-).
, , - MVP, , , .
. , , !
, :
- ( );
- ( Event Aggregator);
-
,
, MVP
Passive View
Application Controller
Application Controller Event Aggregator
Application Controller
MVP ,
Presenter
IPresenter, , Run . .
, , , :
Controller.Run<MainPresener, User>(user); View.Close();
...
View.Close()
, , . , Application.Run(Form)
Windows . , ExitThread
Form.Closed
, .
, - : Application.Run(ApplicationContext)
, ApplicationContext.MainForm
. , (instance) ApplicationContext ( DI) . :
// LoginForm public new void Show() { _context.MainForm = this; Application.Run(_context); } // MainForm public new void Show() { _context.MainForm = this; base.Show(); }
. " " Controller.Run<ChangeUsernamePresenter, User>(user)
. - , ApplicationContext:
public new void Show() { ShowDialog(); }
, , Form.
... ?
, , :
, ( ). , , - . [] , , . [] . .
IoC- IContainer -.
c Github ( Nuget-).
, , - MVP, , , .
. , , !
, :
- ( );
- ( Event Aggregator);
-
,
, MVP
Passive View
Application Controller
Application Controller Event Aggregator
Application Controller
MVP ,
Presenter
IPresenter, , Run . .
, , , :
Controller.Run<MainPresener, User>(user); View.Close();
...
View.Close()
, , . , Application.Run(Form)
Windows . , ExitThread
Form.Closed
, .
, - : Application.Run(ApplicationContext)
, ApplicationContext.MainForm
. , (instance) ApplicationContext ( DI) . :
// LoginForm public new void Show() { _context.MainForm = this; Application.Run(_context); } // MainForm public new void Show() { _context.MainForm = this; base.Show(); }
. " " Controller.Run<ChangeUsernamePresenter, User>(user)
. - , ApplicationContext:
public new void Show() { ShowDialog(); }
, , Form.
... ?
, , :
, ( ). , , - . [] , , . [] . .
IoC- IContainer -.
c Github ( Nuget-).
, , - MVP, , , .
. , , !
, :
- ( );
- ( Event Aggregator);
-
,
, MVP
Passive View
Application Controller
Application Controller Event Aggregator
Application Controller
MVP ,
Presenter
Source: https://habr.com/ru/post/211899/
All Articles