I'm writing login window using WPF, MVVM and dependency injection patterns. My problem is that I must create connection string using login and password which user writes in my login form and I don't know how to do it according to good practice. Object is created by SimpleIoc class and I pass part of connection string like database adress and port during initialization. When user write his login and password I need to pass this data to database manager to create full connection string. I don't want to pass login and password every time when some function is called to connect part of connection string with user and password. I can create function in interface like Initialize but in my point of view that it isn't good idea and I think there is better way to do it.
Here is sample how I do it:
public interface ILoginService
{
bool SomeAction(string parameter);
}
public class LoginService : ILoginService
{
private string _connectionString;
public LoginService(string connectionStringPart)
{
_connectionString = connectionStringPart;
}
public bool SomeAction(string parameter)
{
//Create connection, execute query etc.
return true;
}
}
public class MainViewModel : ViewModelBase
{
private ILoginService _loginService;
private string _login;
public string Login
{
get { return _login; }
set
{
_login = value;
RaisePropertyChanged("Login");
}
}
private string _password;
public string Password
{
get { return _password; }
set
{
_password = value;
RaisePropertyChanged("Password");
}
}
public MainViewModel(ILoginService loginService)
{
_loginService = loginService;
}
private RelayCommand _loginCommand;
public ICommand LoginCommand
{
get { return _loginCommand ?? (_loginCommand = new RelayCommand(ExecuteLogin)); }
}
private void ExecuteLogin()
{
//And here I must add login and password to _loginService but I don't want to do it by passing them to SomeAction method
_loginService.SomeAction("some parameter");
}
}
public class ViewModelLocator
{
public ViewModelLocator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
SimpleIoc.Default.Register<ILoginService>(()=>{return new LoginService("Server=myServerAddress;Database=myDataBase;");});
SimpleIoc.Default.Register<MainViewModel>();
}
public MainViewModel Main
{
get
{
return ServiceLocator.Current.GetInstance<MainViewModel>();
}
}
public static void Cleanup()
{
// TODO Clear the ViewModels
}
}
How About:
public interface ILoginService
{
bool SomeAction(string parameter);
string Password {set; }
string UserName {set; }
}
public class LoginService : ILoginService
{
private System.Data.SqlClient.SqlConnectionStringBuilder builder = new System.Data.SqlClient.SqlConnectionStringBuilder();
private string _connectionString
{
get
{ return builder.ConnectionString;}
}
public LoginService(string connectionStringPart)
{
_connectionString = connectionStringPart;
}
public string Password
{
set { builder["Password"] =value; }
}
public string UserName
{
set { builder["user"] =value; }
}
public bool SomeAction(string parameter)
{
//Create connection, execute query etc.
return true;
}
}
public class MainViewModel : ViewModelBase
{
private ILoginService _loginService;
private string _login;
public string Login
{
get { return _login; }
set
{
_login = value;
_loginService.UserName = value;
RaisePropertyChanged("Login");
}
}
private string _password;
public string Password
{
get { return _password; }
set
{
_password = value;
_loginService.Password= value;
RaisePropertyChanged("Password");
}
}
public MainViewModel(ILoginService loginService)
{
_loginService = loginService;
}
private RelayCommand _loginCommand;
public ICommand LoginCommand
{
get { return _loginCommand ?? (_loginCommand = new RelayCommand(ExecuteLogin)); }
}
private void ExecuteLogin()
{
_loginService.SomeAction("some parameter");
}
Related
I'm trying to implement dependency injection and EF 6 in a WPF on .NET Core 6 project. Part of my code on App.xaml.cs is:
public partial class App : MvxApplication
{
public static IHost? AppHost { get; private set; }
public App()
{
AppHost = Host
.CreateDefaultBuilder()
.ConfigureServices((hostContext, services) =>
{
services.AddSingleton<MainWindow>();
services.AddSingleton<SuperheroContext>();
services.AddSingleton<IUnitOfWork, UnitOfWork>();
services.AddSingleton<IMethodsBusinessLogic, MethodsBusinessLogic>();
IConfiguration configuration;
configuration = new ConfigurationBuilder()
.AddJsonFile(#"appsettings.json")
.Build();
services.AddDbContext<SuperheroContext>(options =>
options.UseSqlServer(configuration.GetConnectionString("Default")));
})
.Build();
}
protected override async void OnStartup(StartupEventArgs e)
{
await AppHost!.StartAsync();
var startupForm = AppHost.Services.GetRequiredService<MainWindow>();
startupForm.Show();
base.OnStartup(e);
}
protected override async void OnExit(ExitEventArgs e)
{
await AppHost!.StopAsync();
base.OnExit(e);
}
protected override void RegisterSetup()
{
this.RegisterSetupType<MvxWpfSetup<_App.App>>();
}
}
I have a view model for navigation purposes and my goal is the CRUD operation.
So I have a CreateViewModel:
public class CreateHeroViewModel : MvxViewModel
{
private readonly IMvxNavigationService navigator;
public CreateHeroViewModel(IMvxNavigationService navigator)
{
this.navigator = navigator;
BackToNavigationManagerCommand = new
MvxCommand(BackToNavigationManager);
CreateTheNewHeroCommand = new MvxCommand(CreateTheNewHero);
}
public ICommand BackToNavigationManagerCommand { get; set; }
public void BackToNavigationManager()
{
navigator.Navigate<NavigationManagerViewModel>();
}
public ICommand CreateTheNewHeroCommand { get; set; }
public async void CreateTheNewHero()
{
//await methodsBusinessLogic.CreateHero(SuperheroModel);
}
private SuperheroModel _superheroModel = new SuperheroModel();
public SuperheroModel SuperheroModel
{
get { return _superheroModel; }
set
{
SetProperty(ref _superheroModel, value);
RaiseAllPropertiesChanged();
}
}
private string _heroName;
private string _heroImage;
private string _firstName;
private string _lastName;
private string _location;
private string _rank;
private string _numberOfFriends;
public string HeroName
{
get { return _heroName; }
set
{
SetProperty(ref _heroName, value);
RaisePropertyChanged(SuperheroModel.HeroName);
}
}
public string HeroImage
{
get { return _heroImage; }
set
{
SetProperty(ref _heroImage, value);
RaisePropertyChanged(SuperheroModel.HeroImage);
}
}
public string FirstName
{
get { return _firstName; }
set
{
SetProperty(ref _firstName, value);
RaisePropertyChanged(SuperheroModel.FirstName);
}
}
public string LastName
{
get { return _lastName; }
set
{
SetProperty(ref _lastName, value);
RaisePropertyChanged(SuperheroModel.LastName);
}
}
public string Location
{
get { return _location; }
set
{
SetProperty(ref _location, value);
RaisePropertyChanged(SuperheroModel.Location);
}
}
public string Rank
{
get { return _rank; }
set
{
SetProperty(ref _rank, value);
RaisePropertyChanged(SuperheroModel.Rank);
}
}
public string NumberOfFriends
{
get { return _numberOfFriends; }
set
{
SetProperty(ref _numberOfFriends, value);
RaisePropertyChanged(SuperheroModel.NumberOfFriends);
}
}
}
The problem arises when I'm trying to inject to the constructor one of my configured services, for example the SuperheroContext.
I've searched to many places but couldn't find out why it's not working.
Any help is welcome!
I am studying the mvvm pattern and ran into a problem, I need to make sure that the button is inactive when the user entered his data incorrectly
I have dialog window (loginPage) where i vote Login and Password
public class LoginViewModel : ViewModel
{
ApplicationDbContext db;
IEnumerable<User> users;
IAuthorizationService _authorizationService;
IHashingManager _hashingManager;
private bool? _closeWindow;
private RelayCommand _loginUser;
private RelayCommand _cancelCommand;
public bool EnableClose { get; set; }
public LoginViewModel(IViewFactory viewFactory, ICore core) : base(viewFactory)
{
_authorizationService = core.AuthorizationService;
_hashingManager = core.HashingManager;
db = new ApplicationDbContext();
}
public ICommand Command { get; set; }
private string login;
public string Login
{
get => login;
set
{
login = value;
RaisePropertyChanged(nameof(Login));
}
}
private string password;
public string Password
{
get => password;
set
{
password = value;
RaisePropertyChanged(nameof(Password));
}
}
public RelayCommand CancelCommand
{
get
{
return _cancelCommand ??
(_cancelCommand = new RelayCommand(() =>
{
var result = _authorizationService.Login(Login, _hashingManager.Encrypt(Password));
CloseWindow = true;
}));
}
}
public bool? CloseWindow
{
get { return _closeWindow; }
set
{
_closeWindow = value;
RaisePropertyChanged(nameof(CloseWindow));
}
}
public RelayCommand LoginUser
{
get
{
return _loginUser ??
(_loginUser = new RelayCommand(() =>
{
var result = _authorizationService.Login(Login, _hashingManager.Encrypt(Password));
CloseWindow = true;
}));
}
}
public IEnumerable<User> Users
{
get { return users; }
set
{
users = value;
RaisePropertyChanged("Users");
}
}
}
My MainWindow VM
public class MainViewModel : ViewModel
{
private readonly ICore _core;
public ICommand LoginCommand { get; }
public ObservableCollection<ILayoutElementViewModel> Documents { get; private set; }
public MainViewModel(IViewFactory viewFactory, ICore core) : base(viewFactory)
{
_core = core;
this.Documents = new ObservableCollection<ILayoutElementViewModel>();
}
ServiceResult _serviceResult = new ServiceResult();
private RelayCommand openChartView;
public RelayCommand OpenChartView
{
get
{
return openChartView ??
(openChartView = new RelayCommand(()=>
{
if (_serviceResult.IsSucceed)
{
var chartView = new ChartSelectionViewModel(_viewFactory);
_viewFactory.ShowDialogView(chartView);
}
}));
}
}
private string _myProperty;
public string MyProperty
{
get => _myProperty;
set
{
_myProperty = value;
RaisePropertyChanged(() => MyProperty);
}
}
protected override void LoadedExecute()
{
base.LoadedExecute();
_viewFactory.ShowDialogView(new LoginViewModel(_viewFactory, _core));
}
}
When i wrote corectly or not, my dialog window close and main window becomes active.
There is a button , and i want disable this button when the login and password was incorrect.
I think i must use my ServiceResult in MW
public class ServiceResult
{
public bool IsSucceed { get; set; }
public string Error { get; set; }
public ServiceResult()
{
IsSucceed = true;
}
public ServiceResult(string error)
{
IsSucceed = false;
Error = error;
}
}
or
AuthorizationService
public class AuthorizationService : IAuthorizationService
{
public ServiceResult Login(string login,string password)
{
ApplicationDbContext db = new ApplicationDbContext();
var listUsers = db.Users.ToList();
foreach (var item in listUsers)
{
if (item.Login == login && item.Password == password)
{
return new ServiceResult();
}
}
return new ServiceResult("Wrong Login or Password!");
}
}
How can i do that? Thx u.
I done, it was so easy
protected override void LoadedExecute()
{
base.LoadedExecute();
var vm = new LoginViewModel(_viewFactory, _core);
_viewFactory.ShowDialogView(vm);
IsAuth = vm.AuthorizationResult;
}
private RelayCommand openChartView;
public RelayCommand OpenChartView
{
get
{
return openChartView ??
(openChartView = new RelayCommand(()=>
{
if (IsAuth)
{
var chartView = new ChartSelectionViewModel(_viewFactory);
_viewFactory.ShowDialogView(chartView);
}
}));
}
}
You can do a bool binding to the IsEnable property of the button.
code:
public bool Enabled
{
get => _enabled; set
{
_enabled = value;
NotifypropertyChanged("Enabled");
}
}
xaml:
<Button IsEnabled="{Binding Enabled}"></Button>
I have 2 independent projects, registration and the main window with a login,I made binding to the same SQLite file.
The user registers everything is fine, but now I need that the login would work correctly. How to extract the user from BD and to make check whether such user exists and whether the password coincides using MVVM?
I'm start to create 2 classes
public class ServiceResult
{
public bool IsSucceed { get; set; }
public string Error { get; set; }
public ServiceResult()
{
IsSucceed = true;
}
public ServiceResult(string error)
{
IsSucceed = false;
Error = error;
}
}
and
public class AuthorizationService
{
public ServiceResult Login(string login,string password)
{
ApplicationDbContext db= new ApplicationDbContext();
return new ServiceResult();
}
}
My Register ViewModel
public class RegisterViewModel : BaseViewModel
{
Hashing hashing = new Hashing();
ApplicationDbContext db;
private string name;
public string Name
{
get => name;
set
{
name = value;
OnPropertyChanged(nameof(Name));
}
}
private string lastName;
public string LastName
{
get => lastName;
set
{
lastName = value;
OnPropertyChanged(nameof(LastName));
}
}
private string login;
public string Login
{
get => login;
set
{
login = value;
OnPropertyChanged(nameof(Login));
}
}
private string password;
public string Password
{
get { return password; }
set
{
if (password != value)
{
password = value;
OnPropertyChanged("Password");
}
}
}
private string mail;
public string Mail
{
get => mail;
set
{
mail = value;
OnPropertyChanged(nameof(Mail));
}
}
public ICommand Command { get; set; }
private RelayCommand registerCommand;
public RelayCommand RegisterCommand
{
get
{
return registerCommand ??
(registerCommand = new RelayCommand(() =>
{
var _user = new RegisterUser(Name, LastName, Login, hashing.Encrypt(Password), Mail);
db.Users.Add(_user);
db.SaveChanges();
}));
}
}
public ObservableCollection<User> Users { get; set; }
public RegisterViewModel()
{
db = new ApplicationDbContext();
}
}
This is Login ViewModel
ApplicationDbContext db;
IEnumerable<User> users;
public LoginViewModel(IViewFactory viewFactory, ICore core) : base(viewFactory)
{
db = new ApplicationDbContext();
}
public ICommand Command { get; set; }
private string login;
public string Login
{
get => login;
set
{
login = value;
RaisePropertyChanged(nameof(Login));
}
}
private string password;
public string Password
{
get => password;
set
{
password = value;
RaisePropertyChanged(nameof(Password));
}
}
private RelayCommand addCommand;
public RelayCommand AddCommand
{
get
{
return addCommand ??
(addCommand = new RelayCommand(() =>
{
}));
}
}
public IEnumerable<User> Users
{
get { return users; }
set
{
users = value;
RaisePropertyChanged("Users");
}
}
}
I done , it's was easy )
public class AuthorizationService
{
ApplicationDbContext db = new ApplicationDbContext();
public ServiceResult Login(string login,string password)
{
var listUsers= db.Users.ToList();
foreach (var item in listUsers)
{
if (item.Login == login || item.Password == password)
{
return new ServiceResult();
}
}
return new ServiceResult("Wrong Login or Password!");
}
}
and Login ViewModel
private RelayCommand loginUser;
public RelayCommand LoginUser
{
get
{
return loginUser ??
(loginUser = new RelayCommand(() =>
{
var result = _authorizationService.Login(Login, hashing.Encrypt(Password));
}));
}
}
How to use the AppSetting on Xamarin plugin. I installed it. Now how to use it, I'm using Entry field with name on it to get the email address from the EmailEntry on xmlfile.
I tried some code on Main Page but the email entered is not getting save.
Settings.cs
namespace DrainLog.Utils
{
public static class Settings
{
private static ISettings AppSettings
{
get
{
return CrossSettings.Current;
}
}
#region Setting Constants
private const string LastEmailSettingsKey = "last_email_key";
private static readonly string SettingsDefault = string.Empty;
#endregion
public static string LastUsedEmail
{
get
{
return AppSettings.GetValueOrDefault(LastEmailSettingsKey,
SettingsDefault);
}
set
{
AppSettings.AddOrUpdateValue(LastEmailSettingsKey, value);
}
}
}
}
MainPage
namespace DrainLog
{
public partial class MainPage : ContentPage
{
public static string item;
public MainPage()
{
InitializeComponent();
drainquatity();
EmailAddress = DrainLog.Utils.Settings.LastUsedEmail;
}
public string emailAddress;
public string EmailAddress
{
get{return emailAddress;}
set
{
emailAddress = value;
DrainLog.Utils.Settings.LastUsedEmail = value;
}
private void EnterButton_clicked(object sender, EventArgs e)
{
bool isNameEmpty = string.IsNullOrEmpty(nameEntry.Text);
bool isEmailEmpty = string.IsNullOrEmpty(emailEntry.Text);
if (isNameEmpty || isEmailEmpty)
{
}
else
{
Navigation.PushAsync(new HomePage());
}
}
}
}
}
I want to be able to save the email address that the user entered so when the user exits the app then re opens it. It's still there live it's save.
I am new in programming and trying to learn singleton but stuck in somewhere.
Here is my user class:
public class User
{
private static User user;
private User()
{
}
private int id;
public int Id
{
get { return id; }
set { id = value; }
}
private string isim;
public string Isim
{
get { return isim; }
set { isim = value; }
}
private string soyad;
public string Soyad
{
get { return soyad; }
set { soyad = value; }
}
public static User CreateUser()
{
if (user == null)
user = new User();
return user;
}
}
In my web form I tried this:
User myuser = User.CreateUser();
to create an object but it gives me an error like there is nothing as CreateUser()..What am I doing wrong
All you have to do is like following:
You have to modify The User class to make it like this
public class User
{
public int Id { get; set; }
public string Isim { get; set; }
public string Soyad { get; set; }
public class User(){}
public User(int id, string isim, string soyad)
{
Id = id;
Isim = isim;
Soyad = soyad;
}
}
Then you implement Singleton (user buisiness logic) class like this
using System;
public sealed class UserBusiness
{
private static volatile UserBusiness instance;
private static readonly object syncRoot = new Object();
private UserBusiness() { }
public static UserBusiness Instance
{
get
{
if (instance == null)
{
lock (syncRoot)
{
if (instance == null)
instance = new UserBusiness();
}
}
return instance;
}
}
public void AddUser(User userToAdd)
{
//TODO use your ORM or whatever to acces database and add the user
//for example if you use entityFramework you will need to do
//Context.Customers.Add(user)
//Context.SaveChanges();
//Just For Example
}
}
There are many implementation of singleton like mentioned in this MSDN article
and finally in your webForm Code you put the following :
var newUser = new User(1, "user1Isim", "user1Soyad");
UserBusiness.Instance.AddUser(newUser);
After All, there are many ways to do this, depends on your needs. I found this as the simpliest way to explain.