StackOverFlow exception in getter - c#

I'm using the Singleton design pattern and I must return the object if it hasn't been used before.
I get an exception in the following code :
namespace app.Models
{
public class Conexion:DbContext
{
private static Conexion Instance = null;
private Conexion(string con) : base(con) { }
public static Conexion MainConexion
{
get {//error here
if (Instance == null)
{
Instance = new Conexion(#"Server=*****; User Id=***;Password=****; Database=****");
}
return Instance;
}
}
public DbSet<label> Labels { get; set; }
public DbSet<checke_status> CheckStatus { get; set; }
public void SaveChanges()
{
MainConexion.SaveChanges();
}
}
}
How can I solve this?

Remove the override of the SaveChanges method:
namespace app.Models
{
public class Conexion : DbContext
{
private static Conexion Instance = null;
private Conexion(string con) : base(con) { }
public static Conexion MainConexion
{
get
{ //error here
if (Instance == null)
{
Instance = new Conexion(
#"Server=*****; User Id=***;Password=****; Database=****");
}
return Instance;
}
}
public DbSet<label> Labels { get; set; }
public DbSet<checke_status> CheckStatus { get; set; }
}
}
Since you have a private constructor, the only instance of this class that can be used is the one exposed in the MainConexion property. It looks like you were trying to make sure that when any instance's SaveChanges method was called that the SaveChanges method on the MainConnection property's instance was called. This is not necessary, because you can only ever have one instance of the Conexion class, and it's the instance that you want to call SaveChanges on. The usage is still the same:
Conexion.MainConexion.SaveChanges();
That being said, I think you would have better luck if you were to not implement it this way. It would probably be better to open and close connections as they were needed, rather than rely on a single connection instance. What happens if the connection is interrupted? Rather than getting a single error, your application will be broken.

Related

c# initialize static variable from different classes

What I have is:
public static class IDs {
public static string someID { get; set; }
static IDs() {
log.info(someID);
// use someID here
}
}
public class otherClass {
public void otherMethod(string sym) {
IDs.someID = sym;
}
}
and then using an instance of otherClass like this:
otherClassInstance.otherMethod("someStringSymbol");
I dont have any build errors, but log.info(someID); is printing null.
I was expecting it to be someStringSymbol.
This is because the static constructor is called automatically before the first instance is created or any static members are referenced..
This means that when an instance of otherClass invokes IDs.someID = sym; the first operation that gets executed is the static constructor, i.e. the code inside static IDs().
At this point the static variable has not yet been initialized, and you are basically executing log.info(null);.
After the static constructor completes, the variable is initialized, so you should be able to see its value inside otherMethod, after the first reference of IDs.
Given the OP's requirement:
I want to use the value passed in someID in a switch statement
The solution could be to simply execute a static method whenever a new value is set, with the help of explicit getters and setters:
public static class IDs
{
private static string _someID; // backing field
public static string SomeID
{
get { return _someID; }
set
{
_someID = value;
DoSomethingWithSomeID();
}
}
private static DoSomethingWithSomeID()
{
// Use SomeID here.
switch (IDs.SomeID)
{
...
}
}
}
public class OtherClass
{
public void OtherMethod(string sym)
{
// This will set a new value to the property
// and invoke DoSomethingWithSomeID.
IDs.SomeID = sym;
}
}
DoSomethingWithSomeID will be invoked every time someone sets a new value to SomeID.
I dont think what you are trying to do is suited to static classes. I would try the following
public class IDs{
public string someID{ get; set; }
public IDs(string someId){
this.someID = someId;
log.info(this.someID);
//use someID here
}
}
pulic class otherClass{
public otherMethod(string sym){
IDs id = new IDs(sym);
}
}
public class anotherClass{
//access instance of otherClass in wrp and call otherMethod()
wrp.otherMethod("someStringSymbol")
}

Can't call C# function from other .cs file

I am really stuck on calling my function InlogLeerling() from .cs file Login.cs into MainPage.xaml.cs.
I did try everything and I already found some answers but I do not understand how I can get it working in my project. When i call the function InlogLeerling() I get the error There is no argument given that corresponds to the required formal parameter 'mainpage' of 'Login.InlogLeerling(MainPage)'
Here is the code I am using in my Login.cs
namespace VerlofXamarin.Logical_Layer
{
public class Login
{
public string pu_Gebruikersnaam, pu_Wachtwoord, pu_LogLeerling;
string Gebruikersnaam
{
get { return pu_Gebruikersnaam; }
set { pu_Gebruikersnaam = value; }
}
string Wachtwoord
{
get { return pu_Wachtwoord; }
set { pu_Wachtwoord = value; }
}
public MainPage mainpage;
private void InlogLeerling(MainPage mainpage)
{
Data_Layer.Verbinding vv = new Data_Layer.Verbinding();
this.mainpage = mainpage;
try
{
if(string.IsNullOrEmpty(pu_Gebruikersnaam) == true || string.IsNullOrEmpty(pu_Wachtwoord) == true)
{
mainpage.pu_LeerlingLog = "Vul gebruikersnaam en wachtwoord in!";
return;
}
vv.con.Open();
MySql.Data.MySqlClient.MySqlCommand cmd = new MySql.Data.MySqlClient.MySqlCommand("SELECT leerlinggebruikersnaam, leerlingwachtwoord FROM arabignl_project.myfirstmodule$leerlinglogin WHERE (leerlinggebruikersnaam = #gebruiker AND leerlingwachtwoord = #wachtwoord)", vv.con);
cmd.Parameters.AddWithValue("#gebruiker", pu_Gebruikersnaam.ToString());
cmd.Parameters.AddWithValue("#wachtwoord", pu_Wachtwoord.ToString());
MySqlDataReader reader = cmd.ExecuteReader();
if (reader.HasRows)
{
while (reader.Read())
{
mainpage.pu_LeerlingLog = "Inloggen gelukt";
}
}
else
{
mainpage.pu_LeerlingLog = "Inloggen mislukt";
}
reader.Close();
}
catch (MySqlException ex)
{
mainpage.pu_LeerlingLog = ex.ToString();
}
finally
{
vv.con.Close();
}
}
}
}
And the MainPage.xaml.cs
namespace VerlofXamarin
{
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
}
public Login login;
public string pu_LeerlingLog
{
get { return LoginLog.Text; }
set { LoginLog.Text = value; }
}
public string pu_LeerlingGebruikersnaam
{
get { return LeerlingGebruikersnaam.Text; }
}
public string pu_LeerlingWachtwoord
{
get { return LeerlingWachtwoord.Text; }
}
public void LoginKlik(Login login)
{
this.login = login;
login.InlogLeerling();
}
I have already tried so many things.
You have two problems in your code.
You can´t call any private member from outside your class. So make your method public
your method expects a parameter of type MainPage. So you have to provide it, which is exactly what your error states:
public void LoginKlik(Login login)
{
this.login = login;
login.InlogLeerling(this);
}
Apart from those you shouldn´t expose a field publicily. Instead use a public property which you can modify within your class and read outside your class Login:
public MainPage MainPage { get; private set; }
You should study access modifier. With private, other classes could not access it. So you could change it to either internal or public. Here is reference
- https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/access-modifiers
internal void InlogLeerling(MainPage mainpage)
You will not be able to call the method because they are not in same class.
When you give an access modifier of privte, the accesses is possible only within the class.
If you would like to give more access there is:
protected - A protected member is accessible within its class and by derived class instances.
Internal- Internal types or members are accessible only within files in the same assembly.(i.e. the same compiled program)
public- . Public access is the most permissive access level. There are no restrictions
Therefor by using internal or public (depends on what you need in more large aspect) you will be able to access this method within other classes in your project

C# Will reflection create multiple instance of a singleton in my assembly?

I am creating a c# based automated testing framework and have configuration files that link test case methods and class names to requirement IDs. The framework will create a TestPlan that is a list of multiple test cases that will executed one after another.
Since there are thousands of testcases (and more all the time) I want to call these classes and methods by reflection, but I am concerned that these methods will create singleton instances of supporting classes that will hang around after the method returns that won't be reused when the next test method is called by reflection.
My question is: will each call use the same static instance in the assembly? Or will each call create a new instance of the singleton? Without reflection in the mix it is a simple answer, but with it ... I am not certain.
Example: I will call SomePageTestCases.TestcaseMethod1() by reflection below. This creates a static instance of CurrentPage which contains the Page object used by the TestMethod. After the Testcase returns, what happens if I call another TestMethod in another class by reflection? Does the CurrentPage.Instance persist and will it be used by the newly called test method? Or will it original be orphaned in the assembly and a new static instance of CurrentPage be created by the new test methods call?
namespace Framework.TestCases
{
public class SomePageTestCases
{
public bool TestCaseMethod1()
{
return (CurrentPage.Instance.Page as SomePage)?.DoSomething() ?? false;
}
}
}
namespace Framework
{
public class CurrentPage
{
private object TopLevelControl;
private static CurrentPage _instance;
public static CurrentPage Instance => _instance ?? (_instance = new CurrentPage());
private Page _page;
public Page Page
{
get
{
if (_page == null || _page.Name != GetCurrentPageName())
_page = GetCurrentPage();
return _page;
}
}
private CurrentPage()
{
//hooks the top level control of the system under test.
throw new NotImplementedException();
}
private static string GetCurrentPageName()
{
//return the page name of the current page from the TopLevelControl.
throw new NotImplementedException();
}
private static Page GetCurrentPage()
{
//Searches the TopLevelControl for the current PageObject and returns it.
throw new NotImplementedException();
}
}
}
namespace Framework.Base
{
public abstract class Page
{
public string Name { get; private set; }
public object PageObject { get; private set; }
protected void LoadPage(string pageClassName)
{
throw new NotImplementedException();
//Name = something;
//PageObject = something;
}
}
}
namespace Framework.Pages
{
public class SomePage : Page
{
public bool DoSomething()
{
throw new NotImplementedException();
}
public SomePage()
{
LoadPage("SomePage");
}
}
}

Passing a SqlConnection to class library file (dll)

I am busy developing a class library project in C# to be reused and attached to different projects in future. It will mainly be used for Table Valued Parameters. My question is, how do I pass a SQL connection to it? The connection will be instantiated in another (main project) that the .dll gets attached to.
I currently have a Class Library Project, and have a Console Application Project created in the same solution for testing purposed.
One last requirement is that I don't want to use ConfigurationManager as the connection string will not be stored in app.config or web.config and by default the queries must be passed back to the calling application.
I've come accross a couple of links like the one below, but nothing I can really use:
Sharing a connection string
Please excuse the noobness, I am 7 weeks into professional programming.
In your dll, simply require an IDbConnection or IDbCommand. All the method is then properly abstracted against the interfaces for the data access.
For example:
In your shared dll
public static int LookUpIntForSomething(IDbConnection connection)
{
using (var command = connection.CreateCommand())
{
// use command.
}
}
In your calling app
using (var connection = new SqlConnection("ConnectionString"))
{
var int = DbQueries.LookupIntForSomething(connection);
}
This is excellent example for dependency injection. I would recommend using enterprise library unity for this kind of stuff. In your data access layer library I would define interface:
public interface IConnectionProvider {
string ConnectionString { get; }
}
public interface IAccountProvider {
Account GetAccountById(int accountID);
}
internal class AccountProvider : IAccountProvider {
private IConnectionProvider _connectionProvider;
public AccountProvider(IConnectionProvider connectionProvider) {
if (connectionProvider == null) {
throw new ArgumentNullException("connectionProvider");
}
_connectionProvider = connectionProvider;
}
public Account GetAccountById(int accountID) {
Account result;
using(var conn = new SqlConnection(connectionProvider)) {
// retrieve result here
}
return result;
}
}
public static class Bootstrapper {
public static void Init() {
ServiceLocator.AddSingleton<IAccountProvider, AccountProvider>();
}
}
Then in any assembly using your data access library you can define implementation for IConnectionProvider, like this:
internal class WebConnectionProvider : IConnectionProvider {
public string ConnectionString { get { return "Server=..."; } }
}
internal static class WebBootstrapper {
public static void Init() {
Bootstrapper.Init();
ServiceLocator.AddSingleton<IConnectionProvider, WebConnectionProvider>();
}
}
And anywhere after you call WebBootstrapper.Init() in your assembly you can use:
var accountProvider = ServiceLocator.Resolve<IAccountProvider>();
accountProvider.GetAccountById(1);
Service locator:
using System;
using Microsoft.Practices.Unity;
public class ServiceLocator {
private IUnityContainer m_Container = new UnityContainer();
public void Add<TFrom, TTo>() where TTo : TFrom {
m_Container.RegisterType<TFrom, TTo>();
}
public void BuildUp<T>(T instance) {
m_Container.BuildUp<T>(instance);
}
public void BuildUp(Type type, object instance) {
m_Container.BuildUp(type, instance);
}
public void AddSingleton<TFrom, TTo>() where TTo : TFrom {
m_Container.RegisterType<TFrom, TTo>(new ContainerControlledLifetimeManager());
}
public void AddInstance<T>(T instance) {
m_Container.RegisterInstance<T>(instance);
}
public T Resolve<T>() {
return m_Container.Resolve<T>();
}
private static ServiceLocator m_Instance;
public static ServiceLocator Instance {
get { return m_Instance; }
}
static ServiceLocator() {
m_Instance = new ServiceLocator();
}
}
if i understand your requirements correctly,I'm not sure that i do, i would setup a static struct as such
public static struct ConnectionString
{
public int ID;
public string Connection;
public override string ToString()
{
return Connection;
}
public static ConnectionString DataBase1 = new ConnectionString{ ID = 1 , Connection = "YourConnectionStringhere"};
public static ConnectionString DataBase2 = new ConnectionString{ ID = 2 , Connection = "YourConnectionString2here"};
}
and then use it as such
public void SomeMethod()
{
var I = ReferencedDll.DoSomething(ConnectionString.DataBase1.ToString());
}
or
public void SomeMethod()
{
var ClassFromDll = new ReferencedDll.SomeClass(ConnectionString.DataBase1.ToString());
ClassFromDll.DoSomething();
}
of course this leaves your connection strings hard coded which is not ideal

How can Ninject be configured to always deactivate pooled references?

We're using a library that uses pooled objects (ServiceStack.Redis's PooledRedisClientManager). Objects are created and reused for multiple web requests. However, Dispose should be called after each use to release the object back into the pool.
By default, Ninject only deactivates an object reference if it has not been deactivated before.
What happens is that the pool instantiates an object and marks it as active. Ninject then runs the activation pipeline. At the end of the request (a web request), Ninject runs the deactivation pipeline which calls Dispose (and thus the pool marks the object as inactive). The next request: the first pooled instance is used and the pool marks it as active. However, at the end of the request, Ninject does not run its deactivation pipeline because the ActivationCache has already marked this instance as deactivated (this is in the Pipeline).
Here's a simple sample that we've added in a new MVC project to demonstrate this problem:
public interface IFooFactory
{
IFooClient GetClient();
void DisposeClient(FooClient client);
}
public class PooledFooClientFactory : IFooFactory
{
private readonly List<FooClient> pool = new List<FooClient>();
public IFooClient GetClient()
{
lock (pool)
{
var client = pool.SingleOrDefault(c => !c.Active);
if (client == null)
{
client = new FooClient(pool.Count + 1);
client.Factory = this;
pool.Add(client);
}
client.Active = true;
return client;
}
}
public void DisposeClient(FooClient client)
{
client.Active = false;
}
}
public interface IFooClient
{
void Use();
}
public class FooClient : IFooClient, IDisposable
{
internal IFooFactory Factory { get; set; }
internal bool Active { get; set; }
internal int Id { get; private set; }
public FooClient(int id)
{
this.Id = id;
}
public void Dispose()
{
if (Factory != null)
{
Factory.DisposeClient(this);
}
}
public void Use()
{
Console.WriteLine("Using...");
}
}
public class HomeController : Controller
{
private IFooClient foo;
public HomeController(IFooClient foo)
{
this.foo = foo;
}
public ActionResult Index()
{
foo.Use();
return View();
}
public ActionResult About()
{
return View();
}
}
// In the Ninject configuration (NinjectWebCommon.cs)
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<IFooFactory>()
.To<PooledFooClientFactory>()
.InSingletonScope();
kernel.Bind<IFooClient>()
.ToMethod(ctx => ctx.Kernel.Get<IFooFactory>().GetClient())
.InRequestScope();
}
The solutions that we've come up with thus far are:
Mark these objects as InTransientScope() and use other deactivation mechanism (like an MVC ActionFilter to dispose of the object after each request). We'd lose the benefits of Ninject's deactivation process and require an indirect approach to disposing of the object.
Write a custom IActivationCache that checks the pool to see if the object is active. Here's what I've written so far, but I'd like some one else's eyes to see how robust it is:
public class PooledFooClientActivationCache : DisposableObject, IActivationCache, INinjectComponent, IDisposable, IPruneable
{
private readonly ActivationCache realCache;
public PooledFooClientActivationCache(ICachePruner cachePruner)
{
realCache = new ActivationCache(cachePruner);
}
public void AddActivatedInstance(object instance)
{
realCache.AddActivatedInstance(instance);
}
public void AddDeactivatedInstance(object instance)
{
realCache.AddDeactivatedInstance(instance);
}
public void Clear()
{
realCache.Clear();
}
public bool IsActivated(object instance)
{
lock (realCache)
{
var fooClient = instance as FooClient;
if (fooClient != null) return fooClient.Active;
return realCache.IsActivated(instance);
}
}
public bool IsDeactivated(object instance)
{
lock (realCache)
{
var fooClient = instance as FooClient;
if (fooClient != null) return !fooClient.Active;
return realCache.IsDeactivated(instance);
}
}
public Ninject.INinjectSettings Settings
{
get
{
return realCache.Settings;
}
set
{
realCache.Settings = value;
}
}
public void Prune()
{
realCache.Prune();
}
}
// Wire it up:
kernel.Components.RemoveAll<IActivationCache>();
kernel.Components.Add<IActivationCache, PooledFooClientActivationCache>();
Specifically for ServiceStack.Redis's: use the PooledRedisClientManager.DisposablePooledClient<RedisClient> wrapper so we always get a new object instance. Then let the client object become transient since the wrapper takes care of disposing it. This approach does not tackle the broader concept of pooled objects with Ninject and only fixes it for ServiceStack.Redis.
var clientManager = new PooledRedisClientManager();
kernel.Bind<PooledRedisClientManager.DisposablePooledClient<RedisClient>>()
.ToMethod(ctx => clientManager.GetDisposableClient<RedisClient>())
.InRequestScope();
kernel.Bind<IRedisClient>()
.ToMethod(ctx => ctx.Kernel.Get<PooledRedisClientManager.DisposablePooledClient<RedisClient>>().Client)
.InTransientScope();
Is one of these approaches more appropriate than the other?
I have not use Redis so far so I can not tell you how to do it correctly. But I can give you some input in general:
Disposing is not the only thing that is done by the ActivationPipeline. (E.g. it also does property/method injection and excuting activation/deactivation actions.) By using a custom activation cache that returns false even though it has been activated before will cause that these other actions are executed again (E.g. resulting in property injection done again.)

Categories

Resources