Help with Singleton - Setting Auto Properties? - c#

I'm trying to set my Auto Properties but they are non-static and so I get the error "Cannot access non-static property in static context" when trying to set the properties Credentials, Certificate, and UrlEndPoint.
public class PayPalProfile
{
#region Fields
static PayPalProfile _instance;
#endregion
#region Constructors
PayPalProfile()
{
// is only called if a new instance is created
SetProfileState();
}
#endregion
#region Properties
public static PayPalProfile CurrentProfile
{
get
{
if (_instance == null)
_instance = new PayPalProfile();
return _instance;
}
}
public CustomSecurityHeaderType Credentials { get; private set; }
public X509Certificate2 Certificate { get; private set; }
public string UrlEndPoint { get; private set;}
#endregion
#region Methods
private static void SetProfileState()
{
// Set the profile state
SetApiCredentials();
SetPayPalX509Certificate();
}
private static void SetApiCredentials()
{
Credentials = new CustomSecurityHeaderType
{
Credentials =
{
Username = PayPalConfig.CurrentConfiguration.ApiUserName,
Password = PayPalConfig.CurrentConfiguration.ApiPassword
}
};
UrlEndPoint = PayPalConfig.CurrentConfiguration.ExpressCheckoutSoapApiEndPoint;
}
private static void SetPayPalX509Certificate()
{
PayPalCerfiticate paypalCertificate = new PayPalCerfiticate();
Certificate = paypalCertificate.PayPalX509Certificate;
}
#endregion
}

There is no need for SetProfileState, SetApiCredentials and SetPayPalX509Certificate to be static.
SetApiCredentials and SetPayPalX509Certificate are setting values for non static properties and so an instance is required. By removing the static modifiers from the above mentioned methods the properties will be set on the instance being constructed when SetProfileState is called.

This means that you have a static method where you are trying to assign instance properties. As there is no instance available in static methods/properties, the error is given.
The example:
public class Test {
public int InstanceProperty { get; set; }
public static void StaticMethod() {
InstanceProperty = 55; // ERROR HERE
}
}
Instead bothe should either be in static or instance context:
public class Test {
public static int StaticProperty { get; set; }
public static void StaticMethod() {
StaticProperty = 55; // Ok
}
}
public class Test {
public int InstanceProperty { get; set; }
public void InstanceMethod() {
InstanceProperty = 55; // Ok
}
}

Related

C#: How do I share an instance of a class between classes?

I have multiple instances of forms within my windows form application that I instantiate upon loading the main form (including an instance of the main form itself). I would like them to be shared between classes so I can use them from any location. I also need to use the members of each class through these instances.
Please note that I am very confused as to how this works. I don't know how I should be declaring instances of my forms but I only want one instance of each so that I can use the .Hide() method and also use each form's/class's members.
I've tried making the instances as properties but I am not sure how to proceed. I am not sure if that is correct.
// get and set for form instances
public Menu menu { get; set; }
public RandomFacts randomFacts { get; set; }
public QuizMenu qm { get; set; }
public AskHowManyQuestions ahmq { get; set; }
// in the main form load method
menu = new Menu();
randomFacts = new RandomFacts();
qm = new QuizMenu();
ahmq = new AskHowManyQuestions();
That code is all within the same 'main' form.
I hope that you can help me with being able to access these instances globally and help me solve this problem. Thank you for reading about my issue.
Trivial example:
using System;
using System.Collections.Generic;
using System.Linq;
public class Program
{
public static void Main()
{
var NewClassInstance = Singleton.GetSingleton().NewClassInstance;
Singleton.GetSingleton().NewClassInstance.Method();
var OtherClassInstance = Singleton.GetSingleton().OtherClassInstance;
var Proparty = OtherClassInstance.Name;
}
}
public class Singleton
{
public NewClass NewClassInstance {get; private set;}
public OtherClass OtherClassInstance {get; private set;}
private static readonly NewClass _newClass = new NewClass();
private static readonly OtherClass _otherClass = new OtherClass();
private static readonly Singleton _singleton = new Singleton();
private Singleton()
{
NewClassInstance = _newClass;
OtherClassInstance = _otherClass;
// Prevent outside instantiation
}
public static Singleton GetSingleton()
{
return _singleton;
}
}
public class NewClass
{
public NewClass()
{
}
public void Method()
{
}
}
public class OtherClass
{
public string Name {get; set;}
public OtherClass()
{
}
}
You can access this intance doing
Singleton.GetSingleton();
Let leave you an other exemple https://dotnetfiddle.net/C1PB05
I only want one instance of each
Move your declarations to their own Class and implement the Singleton Pattern. Since you are dealing with Forms, you can instantiate them on demand, and set them back to null when they are closed by subscribing to their FormClosed event.
Example usage:
MyForms.menu.Show();
Code:
class MyForms
{
private static Menu _menu = null;
public static Menu menu {
get {
if (_menu == null || _menu.IsDisposed)
{
_menu = new Menu();
_menu.FormClosed += (sender, e) => { _menu = null; };
}
return _menu;
}
}
private static RandomFacts _randomFacts = null;
public static Menu randomFacts
{
get
{
if (_randomFacts == null || _randomFacts.IsDisposed)
{
_randomFacts = new RandomFacts();
_randomFacts.FormClosed += (sender, e) => { _randomFacts = null; };
}
return _menu;
}
}
private static QuizMenu _qm = null;
public static QuizMenu qm
{
get
{
if (_qm == null || _qm.IsDisposed)
{
_qm = new QuizMenu();
_qm.FormClosed += (sender, e) => { _qm = null; };
}
return _qm;
}
}
private static AskHowManyQuestions _ahmq = null;
public static AskHowManyQuestions ahmq
{
get
{
if (_ahmq == null || _ahmq.IsDisposed)
{
_ahmq = new AskHowManyQuestions();
_ahmq.FormClosed += (sender, e) => { _ahmq = null; };
}
return _ahmq;
}
}
}
Just assign them to properties on your forms
// in the main form load method
// Class which holds all of the state shared by these forms
sharedState = new SharedState();
menu = new Menu() { SharedState = sharedState };
randomFacts = new RandomFacts() { SharedState = sharedState };
ahmq = new AskHowManyQuestions() { SharedState = sharedState };
qm = new QuizMenu() { SharedState = sharedState };
Obviously, your forms need to declare a SharedState property:
public SharedState SharedState { get; set; }

Entity framework can't add with singleton

My persons class:
public class User
{
public int Id { get; private set; }
public string Isim { get; set; }
public string Soyad { get; set; }
public User(string isim, string soyad)
{
Isim = isim;
Soyad = soyad;
}
}
My UserBusiness class:
public sealed class UserBusiness
{
JuqueryDbEntities entity = new JuqueryDbEntities();
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)
{
entity.PersonelTable.Add(userToAdd);
entity.SaveChanges();
}
}
And lastly my webform codebehind onclick of a login button:
protected void Button1_Click(object sender, EventArgs e)
{
string isim = TextBox1.Text;
string soyad = TextBox2.Text;
var newUser = new User(isim, soyad);
UserBusiness.Instance.AddUser(newUser);
}
Here is my problem: I get an error in AddUser method of my UserBusiness class.
An error in 'entity.PersonelTable.Add(newUser);' line says
'The best overload method match for 'System.Data.Entity.DbSet.Add(SuperQquery.PersonelTable)' has some invalid arguments.' What am I doing wrong(Btw my Id is autoincrement so I am not setting it any value.)
your problem here is that the method Add of System.Data.Entity.DbSet does simply not take argument of type user.
like mentioned in the error
System.Data.Entity.DbSet.Add(SuperQquery.PersonelTable)' has some
invalid arguments
it takes objects of type SuperQquery.PersonelTable
So what you need to do is change AddUser method
public void AddUser(User userToAdd)
{
SuperQquery.PersonelTable pt = new SuperQquery.PersonelTable();
pt.FieldName1 = userToAdd.Isim;
pt.FieldName2 = userToAdd.Soyad;
entity.PersonelTable.Add(pt);
entity.SaveChanges();
}
where FieldName are names of columns in the table of the database
EDIT: if this works, we can say that you made a conversion of type user to type SuperQquery.PersonelTable the way you can insert data in database, but the best way here is to change the class User by a new class PersonelTable with the same logic. No need to do a conversion.

Using singleton asp.net c#

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.

An object method is required for non static, field method

I've no experience of using C# but as part of one of our college modules we have to create a slot machine application. We created a Gambler class and I have to make a CheckBalance class where I will call the Token method from the Gambler class. But I get the error that is mentioned in the thread title.
Int tokens = Gambler.Tokens;
The above line is where I am getting my error.
This is my code:
enter code herenamespace CasinoClasslibrary
{
public class Gambler
{
public string Name { get; private set; }
public int Age { get; private set; }
public long CreditCardNum { get; private set; }
public int Tokens { get; public set; }
public string Username { get; private set; }
public string Password { private get; public set; }
public Gambler(string Name, int Age, long CreditCardNum, int Tokens, string Username, string Password)
{
this.Name = Name;
this.Age = Age;
this.CreditCardNum = CreditCardNum;
this.Tokens = Tokens;
this.Username = Username;
this.Password = Password;
}
}
public class Cashout : Gambler
{
public Boolean CheckBalance()
{
int tokens = Gambler.Tokens;
return true;
}
}
}
Since you are inheriting from Gambler I suspect that you need to access base.Tokens like:
public Boolean CheckBalance()
{
int tokens = base.Tokens; //here
return true;
}
Otherwise since Toakens is an instance member you have to create object of Gambler and then access it.
There are other errors in your code as well. You haven't defined a default (parameter less) constructor in your base class and you need to call the existing base constructor in your child class.
public class Cashout : Gambler
{
public Cashout()
: base("",0, 0, 1, "", "") //something like this
{
}
public Boolean CheckBalance()
{
int tokens = base.Tokens;
return true;
}
}
Because Cashout inherits from Gambler you can just do this. This is because the Cashout instance will have a Tokens property as well.
public class Cashout : Gambler
{
public Boolean CheckBalance()
{
int tokens = Tokens;
return true;
}
}
However, if you intended the method to be static, you will need an instance of Gambler to access that property and this should be passed into the static method as such.
public class Cashout : Gambler
{
public static Boolean CheckBalance(Gambler myGambler)
{
int tokens = myGambler.Tokens;
return true;
}
}
Finally, if you intended this Tokens property to be static itself, you need to declare it as such
public static int Tokens;
You may also want a static constructor to set it up.
Tokens is not static method but you try to access it through static construct (class level).
can make this work by declaring it static (although that's not likely what you want)
public static int Tokens { get; public set; }
or by instantiating Gambler
new Gambler().Tokens;

Stack overflow error in singleton pattern

I have implemented Single Pattern. Here is my code i am getting the an error when i call the Test.BuildData() function. Please help
public class WordDataItem
{
public string Word { get; set; }
public string Definition { get; set; }
public int WordGroupKey { get; set; }
}
public class WordDataGroup
{
public List<WordDataItem> listItem = new List<WordDataItem>();
public int GroupKey { get; set; }
}
public sealed class WordDataSource
{
private static WordDataSource _dataSoruce;
private List<WordDataGroup> listGroup = new List<WordDataGroup>();
public List<WordDataGroup> ListGroup
{
get { return listGroup; }
set { listGroup = value; }
}
private WordDataSource() { }
public static WordDataSource Instance
{
get
{
if (Instance == null)
{
_dataSoruce = new WordDataSource();
}
return _dataSoruce;
}
}
}
public static class Test
{
public static void BuildData()
{
WordDataSource.Instance.ListGroup.Add(new WordDataGroup() { GroupKey = 8, listItem = new List<WordDataItem>() { new WordDataItem() {Word = "Hello", Definition="Greetings", WordGroupKey = 8}} });
}
}
I get an error of stack over flow when i call the Test.BuildData() function.
Your Instance property is recursively calling into itself when you check if it is null.
Try this:
public static WordDataSource Instance
{
get
{
if (_dataSoruce == null)
{
_dataSoruce = new WordDataSource();
}
return _dataSoruce;
}
}

Categories