I am trying to assign a value to a field variable, so that the value should be assigned to variable in the beginning, as that variable is needed in many methods, and i dont want to call method again and again in every method.
e.g
class MyClass
{
private string conn = "crms";
private string connectionString = myMethod(conn);
public string myMethod(string str)
{
// some code
}
}
but it gives me error, any help?
class MyClass
{
private string _conn = "crms";
private string _connectionString = myMethod(conn);
// Constructor
public MyClass()
{
connectionString = whatever _conn
}
}
Then you can do:
var myClass = new MyClass();
And the private variables will be set
You can either use #Prescott answer or you can modify it a little bit!
something like this:
private string _conn = "crms";
private string _connectionString = myMethod(conn);
// Constructor
public MyClass(string connection)
{
connectionString = whatever _conn
}
and you can use it like that:
var myClass = new MyClass("My Connection String");
if you're asking how to set a private field of a class using a method you can try this:
public string UpdateField(string conn)
{
_conn = conn;
return _conn;
}
this method will update your private field .. and you can delete the constructor if you don't need it.
Related
I have a class library that contains hundreds of static methods and variable as follows…
public class General
{
public static string Con { get; set; }
public static string Func1()
{
using (SqlConnection con = new SqlConnection(Con))
{
// My stuff here
}
}
public static string Func2()
{
using (SqlConnection con = new SqlConnection(Con))
{
// My stuff here
}
}
public static string Funcn()
{
using (SqlConnection con = new SqlConnection(Con))
{
// My stuff here
}
}
}
I referenced this class library to my ASP.Net Webform app and assign connectionstring from Global.asax’s Application_Start event
protected void Application_Start(object sender, EventArgs e)
{
General.Con = ConfigurationManager.ConnectionStrings["Con"].ConnectionString;
}
Everything works fine.
Now that I wanted to change database connectionstring on per-LoggedIn-user basis.
What I have tried:
I stored all user’s connectionstring info at one table in common database and mapped them to respective userIDs.
On Login button click, I could save connectionstring to session.
Session["Con"] = ds.Tables[0].Rows[0][0].ToString();
In class library I used
Public static string Con = System.Web.HttpContext.Current.Session["Con"].ToString();
I get error : Object reference not set to an instance of an object.
If I remove static, all my variable and methods gives an error: An object reference is required for the non-static
If I use new keyword here, error is “Cannot be accessed with an instance reference; qualify it with a type name instead”.
Then I used
public static string Con()
{
string Con = "";
HttpContext httpContext = HttpContext.Current;
if (httpContext.ApplicationInstance.Session.Count > 0)
{
if (httpContext.ApplicationInstance.Session["Con"] != null)
Consd = httpContext.ApplicationInstance.Session["Con"].ToString();
}
return Con;
}
It gives me error: Cannot convert from method group to string
Please help me out…
Your class is static, which means there is a single instance, yet you want to change the connection on a user basis.
That is obviously not going to work. I would personally recommend you allow multiple instances of your class (non-static) and initialize each instance with the connection string as a parameter:
public class General
{
private string _connectionString;
public General(string connectionString)
{
_connectionString = connectionString;
}
}
You can then instantiate it once per session if you want, or simply instantiate it every time you need to use it. I would not recommend adding dependencies into the class (e.g. where the connection string comes to).
var data = new General(ds.Tables[0].Rows[0][0].ToString());
var result = data.Func1();
If for some reason, you need to keep the class static, you would need to either provide the connection string to the function so it can use it, or embed the logic to pull out the connection string from the session into the method:
public static string Func1(string connectionString)
{
using (SqlConnection con = new SqlConnection(connectionString))
{
// My stuff here
}
}
OR
public static string Func1()
{
using (SqlConnection con = new SqlConnection(ds.Tables[0].Rows[0][0].ToString()))
{
// My stuff here
}
}
I would recommend passing the connection string as a parameter if you decide to go this route.
One last option if you wish to keep your class static would be to use a Configurator object that provides the connection string, in order to abstract the location:
public interface IConfigurator
{
string GetConnectionString();
}
public class SessionConfigurator : IConfigurator
{
public string GetConnectionString()
{
var connectionString = Session["Con"].ToString();
return connectionString;
}
}
public static class General
{
public IConfigurator Configurator { get; set; }
public static string Func1()
{
using (SqlConnection con = new SqlConnection(Configurator.GetConnectionString()))
{
// My stuff here
}
}
}
Then upon application startup:
General.Configurator = new SessionConfigurator();
I've created a method that acts as a factory to roll out the type of connection I need. In this case, I'm possibly instantiating types SqlConnection and PrincipalContext, and returning that instance. The method takes in a single parameter, type Object. If the parameter value is of the specified type above, it will create an instance of that object. My issue is the return type of the method is Object, so a cast is required when the method is called.
An example would be:
SqlConnection connection2 = new SqlConnection();
SqlConnection sqlCon = (SqlConnection)ConnectionFactory.RolloutConnectionType(connection2);
And the RolloutConnectionType method:
public static Object RolloutConnectionType(Object obj) {
if (obj == null) {
if (obj is PrincipalContext) {//create new PrincipalContext
string user, pass, domain;
domain = ConfigurationManager.AppSettings["SAdomain"];
user = ConfigurationManager.AppSettings["SAuser"];
pass = ConfigurationManager.AppSettings["SApass"];
obj = new PrincipalContext(ContextType.Domain, domain + ".mydomain.ca", "CN=MyCN,DC=myDC,DC=ca", user, pass);
} else if (obj is SqlConnection) {//create new SqlConnection
string connStr = System.Configuration.ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString;
obj = new SqlConnection(connStr);
}
}
return obj;
}
I think I'm on the right track with this, but it seems very messy and likely redundant with an instance required to create an instance - connection2 to create and return obj in RolloutConnectionType. It works, but I don't like how it works. Is what I'm attempting possible? Are there other avenues I could pursue?
Assuming you want to stick with the factory pattern, you should be looking at something like the following:
public interface Factory<T>
{
T Create();
}
public class PrincipalContextFactory : IFactory<PrincipalContext>
{
public PrinicipalContext Create()
{
// return new PrincipalContext(...);
}
}
public class SqlConnectionFactory : IFactory<SqlConnection>
{
public SqlConnection Create()
{
// return new SqlConnection(...);
}
}
Your factory shouldn't need anything more than to return a new instance of what you're after. You could go generics (Create<T>()), but now you're creating a bunch of edge cases for models not a PrinicpalContext or SqlConnection.
Why not just have your factory class with static methods of each thing your are trying to create and have each method return its own properly type-cast object
public static class YourFactory
{
public static SqlConnection GetConnection()
{
string connStr = System.Configuration.ConfigurationManager
.ConnectionStrings["MyConnectionString"].ConnectionString;
return new SqlConnection(connStr);
}
public static PrincipalContext GetPrincipalContext()
{
string user, pass, domain;
domain = ConfigurationManager.AppSettings["SAdomain"];
user = ConfigurationManager.AppSettings["SAuser"];
pass = ConfigurationManager.AppSettings["SApass"];
return new PrincipalContext(ContextType.Domain, domain + ".mydomain.ca",
"CN=MyCN,DC=myDC,DC=ca", user, pass);
}
}
I am trying to initialize a static variable from a static method but after it has been initialized it is still null. What am I doing wrong?
class Database {
public static Database Connection = null;
public static void Create() {
Database.Connection = new Database();
if (Database.Connection == null) {
Console.WriteLine("Null");
}
}
public Database() {
Console.WriteLine("I got called");
}
}
Am I missing something here? Database.Connection is NULL after calling the method although the constructor has been called.
class Database {
public static Database Connection = null;
static Database() {
Database.Connection = new Database();
if (Database.Connection == null) {
Console.WriteLine("Null");
}
}
public Database() {
Console.WriteLine("I got called");
}
}
You never call the Create(). You can use static constructor for this, if you'd like, as I've done above.
Use Static constructor, to initialize static field.
static Database()
{
Database.Connection = new Database();
}
One option is to make the static member a Property:
class Database
{
private static Database _connection = null;
public static Database Connection
{
get
{
if(null == _connection)
{
_connection = new Database();
}
return _connection;
}
}
}
If you are implementing a singleton, then you should hide the constructor by making it private.
private Database()
{
// This will only be called once, when the Connection
// property getter is first accessed and the private
// _connection field is still null. Note: when using
// the debugger, this may be before it is actually called
// explicitly from within your code!
Console.WriteLine("Database() constructor called");
}
I am a newbie. Sorry!
My Windows Form App has 3 layer. Presentation has Form_Login with textEdit_Name and textEdit_Pass.
My Connection class:
public class _Connection
{
public OleDbConnection GetConn(string _name, string _pass)
{
OleDbConnection _Conn = new OleDbConnection(String.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};User ID={1};Password={2};", #"C:\Test\Test.mdb", _name, _pass));
return _Conn;
}
}
My Data Access Layer:
public class getDAL : IDisposable
{
private _Connection getConn = new _Connection();
OleDbConnection _Conn = new OleDbConnection();
public DataTable getDatatable()
{
_Conn = getConn.GetConn();
//Do something
}
}
How can I get _Conn with:
_name = textEdit_Name.Text and _pass = textEdit_Pass.Text
when user login through Form_Login
Perhaps the simplest method would be to set up the ConnectionString details in a static class in your DAL. Something like this:
public static class ConnectionDetails
{
public static string UserName;
public static string Password;
public static string GetAccessConnectionString(string filepath)
{
StringBuilder sb = new StringBuilder();
sb.AppendFormat("Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};", filepath);
if (string.IsNullOrEmpty(UserName) || string.IsNullOrEmpty(Password))
sb.Append("User Id=admin;Password=;");
else
sb.AppendFormat("User Id={0};Password={1};", UserName, Password);
return sb.ToString();
}
}
Your business layer needs to set the UserName and Password fields of the ConnectionDetails static class whenever they change in your presentation layer, and your DAL classes that need connection strings should get them by calling ConnectionDetails.GetAccessConnectionString with the appropriate file path. Or add FilePath as one of the static fields in that class so that you can set all three from wherever.
If you're intending to use more than one database file then a dictionary of connection data keyed off the file name would probably be a good idea.
You can use the ConnectionStringBuilder Class
public static class BuildConnection()
{
public static GetConnectionString(var userName, var Password)
{
OdbcConnectionStringBuilder builder = new OdbcConnectionStringBuilder();
builder.Driver = "Microsoft Access Driver (*.mdb)";
builder.Add("Dbq", #"C:\Test\Test.mdb");
builder.Add("User Id", userName);
builder.Add("Password", Password);
return builder.ConnectionString; // Here is your connection String
}
}
Here is example how you can pass LoginForm TextBox .Text to Business Layer and Data Access Layer.
Data Access Layer:
class DALClass : IDisposable
{
private _Connection getConn;
OleDbConnection _Conn;
public DALClass()
{
getConn = new _Connection();
}
public DataTable getDatatable(string sUserName, string sUserPass)
{
//pass on user name and password
_Conn = getConn.GetConn(sUserName, sUserPass);
//Do something
return default(DataTable); //return datatable
}
}
public class _Connection
{
public OleDbConnection GetConn(string _name, string _pass)
{
OleDbConnection _Conn = new OleDbConnection(String.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};User ID={1};Password={2};", #"C:\Test\Test.mdb", _name, _pass));
return _Conn;
}
}
Business Layer:
class BLClass
{
DALClass _dal;
public BLClass()
{
_dal = new DALClass();
}
public DataTable GetDataTable(string sUserName, string sUserPass)
{
return _dal.getDatatable(sUserName, sUserPass);
}
}
Login Form:
public partial class LoginForm : Form
{
BLClass _bl;
public LoginForm()
{
InitializeComponent();
//object of business layer
_bl = new BLClass();
}
private void button1_Click(object sender, EventArgs e)
{
//pass text boxes values to Business Layer
DataTable dt = _bl.GetDataTable(textEdit_Name.Text, textEdit_Pass.Text);
}
}
I need to have a class for Variables and Methods for the sake of manageability.
The problem is I am not sure how I can access the value of the variable assigned in the method class.
Here is the variable class, it just holds variables:
namespace Classes
{
class MyVariableClass
{
public string MyVariable { get; set; }
}
}
Here is the method:
I am calling an instance of the variable class in the method class so that I can assign the variable to the values of the method.
namespace Classes
{
class MyMethods
{
MyVariableClass myVarClass = new MyVariableClass();
public void DoSomeStuff(string myString1, string myString2)
{
myVarClass.MyVariable = (!string.IsNullOrEmpty(myString2)
? myString2 : "String 2 has nothing!");
}
}
}
Finally, below is the Main Method:
When I run this code, MyVariable returns null, I am assuming I am accessing the variable before it is assigned it's values?
How do I get the variable with the values assigned in the Method class?
namespace Classes
{
class Program
{
static void Main(string[] args)
{
MyMethods myMethod = new MyMethods();
MyVariableClass myVarClass = new MyVariableClass();
string something = "something";
string nothingHere = null;
myMethod.DoSomeStuff(something, nothingHere);
//I need to call MyVariable here
//Or be able to access it's values assigned in the MyMethod Class.
Console.Write(myVarClass.MyVariable);
Console.ReadKey();
}
}
}
Problem : You are working on two different objects.
you are creating an object with an instance variable myVarClass in MyMethods class.
you are creating one more new object with an instance variable myVarClass in Main() method.
Note : You should always remeber that in object oriented programming objects are independent and maintain their own copy so modifying one object parameters/properties doesnot effect the other object parameters or properties.
Solution : instead of creating two different object create only one object with instance variable myVarClass in Main() method and pass it to the myClass method.
so you should change your myClass method DoSomeStuff() as below to accept the instance variable of `MyVariableClass``
public void DoSomeStuff(MyVariableClass myVarClass, string myString1, string myString2)
{
//do something
}
from Main() method call the above method as below:
MyVariableClass myVarClass = new MyVariableClass();
string something = "something";
string nothingHere = null;
myMethod.DoSomeStuff(myVarClass, something, nothingHere);
Complete Code:
namespace Classes
{
class MyMethods
{
public void DoSomeStuff(MyVariableClass myVarClass, string myString1, string myString2)
{
myVarClass.MyVariable = (!string.IsNullOrEmpty(myString2)
? myString2 : "String 2 has nothing!");
}
}
}
and Main Program should be :
namespace Classes
{
class Program
{
static void Main(string[] args)
{
MyMethods myMethod = new MyMethods();
MyVariableClass myVarClass = new MyVariableClass();
string something = "something";
string nothingHere = null;
myMethod.DoSomeStuff(myVarClass, something, nothingHere);
//I need to call MyVariable here
//Or be able to access it's values assigned in the MyMethod Class.
Console.Write(myVarClass.MyVariable);
Console.ReadKey();
}
}
}
The myVarClass member of MyMethods is private by default, so if you want to be able to call it from outside the class itself, then you need to make it public.
Once public, you'll able to do:
static void Main(string[] args)
{
MyMethods myMethod = new MyMethods();
MyVariableClass myVarClass = new MyVariableClass();
string something = "something";
string nothingHere = null;
myMethod.DoSomeStuff(something, nothingHere);
//I need to call MyVariable here
//Or be able to access it's values assigned in the MyMethod Class.
Console.Write(myMethod.myVarClass.MyVariable);
Console.ReadKey();
}
Also, be careful with the fact that the myVarClass defined in main is a completely different object.
Cheers
Define you class as:
namespace Classes
{
class MyMethods
{
public MyVariableClass MyVarClass {get; private set;}
public void DoSomeStuff(string myString1, string myString2)
{
if(MyVarClass == null)
{
MyVarClass = new MyVariableClass();
}
MyVarClass.MyVariable = (!string.IsNullOrEmpty(myString2)
? myString2 : "String 2 has nothing!");
}
}
}
then use as:
namespace Classes
{
class Program
{
static void Main(string[] args)
{
MyMethods myMethod = new MyMethods();
string something = "something";
string nothingHere = null;
myMethod.DoSomeStuff(something, nothingHere);
//I need to call MyVariable here
//Or be able to access it's values assigned in the MyMethod Class.
Console.Write(myMethod.MyVarClass.MyVariable);
Console.ReadKey();
}
}
}