Click here to Skip to main content
15,036,363 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
Hi Guys,
I have a sln in .Net which is based on 2 projects:
- Wpf application under the name 'Installer' and a class library under the name 'InstallerCore'.
- The 'InstallerCore' is responsible for accessing the data base and basically it is the data layer.

In the wpf app, each user control data context is loaded from a view model and the view model use the 'InstallerCore' to retrieve data by inherit its base class.

My problem is the Instance Builder of the XAML. Once I load one of the user controls I get an exception: "Cannot create an instance of the uc".

Now, this is not exactly the case. If I'm looking through the stack trace, I can see that the inner exception hide a deeper error saying:
"NullReferenceException: Object reference not set to an instance of an object".

Let me show you what's going on in the code:

Lets say I have a class named 'uc_file_system'.
On the code behind, I'm loading its data context from a view model like this:
public partial class uc_file_system : UserControl
    {
        FileSystemViewModel vm;
        public uc_file_system()                                                         
        {
            InitializeComponent();
            vm = new FileSystemViewModel();
            this.DataContext = vm;
        }        
    }

The view model c'tor looks like that:
public class FileSystemViewModel : BaseDA, INotifyPropertyChanged
{
public FileSystemViewModel() : base(GV.InstallerConnectionString)
        {
            GetSomeDataFromDataBase();
        }
void GetSomeDataFromDataBase()
        {
            List<p> prms = new List</p><p>();
            prms.Add(new P() { ParamName = "@description", ParamValue = "InstallationFolder" });
            DataTable res = ExecuteReader(InstallerConsts.GetGlobalParams, prms);
            InstallationBaseFolder = res.Rows[0][0].ToString();
        }
}

The GV.InstallerConnectionString is a property which return a connection string from a static class:
public static class GV // {Global Variables}
    {
        #region Members        
        private static List<connectionstringinfo> connectionStrings;
        #endregion

        #region Properties
        
        public static string InstallerConnectionString
        {
            get { return ConnectionStringInfoHandler.GetConnectionString(ConnectionStrings, ConnectionStringType.Installer); }
        }
        public static List<connectionstringinfo> ConnectionStrings
        {
            get
            {
                return connectionStrings;
            }
            set
            {
                if (connectionStrings == null)
                {
                    connectionStrings = value;
                }
            }
        }
    }


The ConnectionStrings is set in the app.xaml.cs like that:
protected override void OnStartup(StartupEventArgs e)
        {
            GV.ConnectionStrings = (List<connectionstringinfo>)ConfigurationManager.GetSection(ConnectionStringInfoHandler.SectionName);
        }


The BaseDa class under the 'InstallerCore' project looks like that:
public class BaseDA
{
public BaseDA(string connectionString)
        {
            ConnectionString = connectionString;
        }
}

And the connection string is coming from the app.config of the wpf application:

<configuration>
	<configsections>
		</p><section name="connectionStringInfos">
	
	<connectionstringinfos>
		<connectionstringinfo name="Installer" type="Installer" connectionstring="Data Source=localhost\sqlexpress;Initial Catalog=InstallerDB;Integrated Security=True;" providername="System.Data.SqlClient">
	
	<startup>
		<supportedruntime version="v4.0" sku=".NETFramework,Version=v4.5">

Now, it is very important to mention that once I replace the ' GV.InstallerConnectionString' directly with a string that is actually a connection string (hard coded), the exception on the xaml is gone.
It is also important to mention that the code runs with no error during run time no matter what and I manage to get data from the data base.
This is the stack trace:
at InstallerCore.Configuration.ConnectionStringInfoHandler.GetConnectionString(List`1 lst, ConnectionStringType type)
at Installer.Settings.GV.get_InstallerConnectionString()
at Installer.ViewModels.FileSystemViewModel..ctor()
at Installer.UserControls.uc_file_system..ctor()


What I have tried:

Almost everything.................................
Posted
Updated 26-Jul-20 16:02pm
v2

1 solution

hmmm .. I'm not as au fait with xaml etc as I should be .. but looking at this
public static class GV // {Global Variables}
    {
        #region Members        
        private static List<connectionstringinfo> connectionStrings;
        #endregion

        #region Properties
        
        public static string InstallerConnectionString
        {
            get { return ConnectionStringInfoHandler.GetConnectionString(ConnectionStrings, ConnectionStringType.Installer); }
        }

I'd say there's a difference between declaring a List and actually instantiating it with a new(), and the new() is missing

I'm happy to be proven wrong, it was just from a quick observation. Where would one put a new() though ? is a deeper question .. I might try
public static string InstallerConnectionString
        {
            if (null == connectionstrings)
            {
              connectionstrings = new List<connectionstringinfo>();
            }
            get { return ConnectionStringInfoHandler.GetConnectionString(ConnectionStrings, ConnectionStringType.Installer); }
        }
but I still feel that may not be the best approach over using a constructor for your GV class and doing it in that ....

[Edit] : definately
public static GV()
{
  connectionstrings = new List<connectionstringinfo>();
}
is the way to go, I was just trying to indicate 'intent' earlier
   
v4
Comments
oronsultan 27-Jul-20 2:44am
   
Dear Garth,
Thank you very much for your quick reply.
Although the exception still stands, Thanks to your answer I can now point to the object causing the problem. The static property 'InstallerConnectionString' Saying that the List<connectionstringinfo> ConnectionStrings is not initialized. Just to proof it, If I Rewrite the code to this, everything works great:
public static string InstallerConnectionString
{
get
{
List<connectionstringinfo> cs = new List<connectionstringinfo>();
cs.Add(new ConnectionStringInfo() { Type = ConnectionStringType.Installer, ConnectionString = @"Data Source=localhost\sqlexpress;Initial Catalog=InstallerDB;Integrated Security=True;" });
return ConnectionStringInfoHandler.GetConnectionString(cs, ConnectionStringType.Installer);
}
//get { return ConnectionStringInfoHandler.GetConnectionString(ConnectionStrings, ConnectionStringType.Installer); }
}
The problem is that according to the compiler, He is not sure that the ConnectionStrings is actually contain anything.
Garth J Lancaster 27-Jul-20 2:52am
   
Well, I'm not sure why the static constructor init doesnt work
public static GV()
{
  connectionstrings = new List<connectionstringinfo>();
}
oronsultan 27-Jul-20 3:44am
   
Dear Friend,
Initializing the List inside the constructor does not resolve it.
Only when I write the connection string hard coded the error stop, like that:
static GV()
{
connectionStrings = new List<connectionstringinfo>();
connectionStrings.Add(new ConnectionStringInfo() { Type = ConnectionStringType.Installer, ConnectionString = @"Data Source=localhost\sqlexpress;Initial Catalog=InstallerDB;Integrated Security=True;" });
}
But if the constructor just initialize the list, the error still occur:
static GV()
{
connectionStrings = new List<connectionstringinfo>();
}
BTW, static constructor cant be public :-)

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
Top Experts
Last 24hrsThis month



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900