Share the ideas and thoughts, become united ...

Friday, May 27, 2011

Understanding & Solving the "Side by Side Configuration" (DLL Hell) Problem - C++

Many developer has seen the "Side by Side Configuration Error" problem. They build their executable in one system and after transferring the application to another system they got this error. Just by seeing that error one might think - "WTH, does C++ application need dependencies?". The answer is yes if you build Win32 application.


 In win32 application we use the header file to use the function in our application and the library file to successfully link the application to external functions (library functions). This problem occurs due to MS's dynamic link feature. When you build the application the VS linker perform a shared dynamic link to the system library. This linking reduces the size of the executable because the library resides in the OS. Now when you transfer the application to another system & try to run it, you have a high chance of getting the "Side by Side Configuration Error" due to mismatched version of system library resided in the target OS.

The easiest way to solve this problem is to reinstall the MSVC redist package. Most of the time it may save your day. But sometime it may not.

Lets jump into the heart of the problem. Usually the VC redist resides in "%windir%\winsxs". In that folder you will see all the required library to run Win32 C++ application. 

Now the question is which library do we need? Lets get back to our MSVC project. I have created a sample test Win32 application and build it. Now if you go to the debug folder you will see many files. Among them you will see a ".manifest" file. Now open it with a text editor. You will see that that is an xml file. The important part of this file is -
<dependency>
    <dependentAssembly>
      <assemblyIdentity type="win32" name="Microsoft.VC90.DebugCRT" version="9.0.21022.8" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>
    </dependentAssembly>
  </dependency>
This section tells us which library & which version we will need to run the program. In the winsxs folder you will get the library in this format -
processorArchitecture_name_publicKeyToken_version
 That folder contains the required library files. I hope you have understood the dependency search. Now I am going to share another working solution. 

In MSVC you can link the required library as static. To do so go to solution's properties --> Expand the Configuration Properties --> General. You will see use of MFC, ATL configuration entries under the project defaults. 


The default value for the entry is "Use standard windows library". Change it to "Use MFC in a static library". You should set this option in ATL configuration entry if you use ATL. Now build the solution and thats it. Now your executable will be bigger but it won't require the windows library from winsxs folder.

The "Side by Side Configuration" error snapshot is by courtesy of google :). And the later snapshot is taken from MSVS 2008.

Hope this article will help you. If you have any question or queries please leave a comment.

Saturday, May 21, 2011

C# - ComboBox + DataSet, ADO.NET

Source

In my last post I talked about the ADO.NET. Today I am going to demonstrate how fast you can build the application using the ADO.NET. 

My example will have two solution one is a class library (DLL) which will implement the database functionalities. Another solution will use that DLL to talk to the database and do some work with it.

I am using MySQL database. You can use any database instead of MySQL. My database (mydb) contains only two tables. These table follows -
---- info -----                    ---- detailed_info ----
    id(pk) | name                        id(fk) | email

Now first let us focus on database implementation. I took an abstract class which has two member. One is IdbConnection & another is String. It also has two virtual method open & fillDataSet. The code looks like below - 

    abstract public class DB {
        IDbConnection _connection;
        String _connStr;

        public IDbConnection Connection { set { this._connection = value; } get { return _connection; } }
        public String ConnStr { set { _connStr = value; } get { return _connStr; } }

        public abstract void open();
        public abstract void fillDataSet(ref DataSet dtSet, String query, String dataTableName);
    }
 This is our base class & we will inherit this class to make database specific implementation. I have took another class named MySQLDB and made it a child of DB class. As MySQL connection string is specific to MySQL database only. So that information is loaded to base classes ConnStr variable whenever we create an instance of MySQLDB class. Implementation of the class looks like this -

public class MySQLDB : DB
    {
        private String[] strMySQL = new String[] { "localhost", "root", "123", "mydb" };
        
        public MySQLDB()
        {
            this.ConnStr = String.Format("server={0};userid={1};password={2};Database={3};Character Set=utf8;", strMySQL[0], strMySQL[1], strMySQL[2], strMySQL[3]);
        }

        override public void open()
        {
            Debug.Assert(ConnStr != null);
            Connection = new MySql.Data.MySqlClient.MySqlConnection(ConnStr);
            Debug.Assert(Connection != null);
        }

        override public void fillDataSet(ref DataSet dtSet, String query, String dataTableName)
        {
            MySql.Data.MySqlClient.MySqlDataAdapter Adapter = new MySql.Data.MySqlClient.MySqlDataAdapter(query, (MySql.Data.MySqlClient.MySqlConnection)Connection);
            Debug.Assert(Adapter != null);
            Adapter.Fill(dtSet, dataTableName);
        }
    }
 As you can see that I have overrode the two virtual function declared in base class. In the open function the main task was to create the connection to the database using a connection string. In the fillDataSet function we took a dataadapter object and fill the given dataset with appropriate data by querying the database using the provided query.

Now we will introduce an interface which will contain the database function and a class which will actually implement the interface.

   public enum DBTYPE
    {
        MYSQL
    }

public interface DBFunctions
    {
        void getUserInfo(ref DataSet dtSet);
        void getUserDetailedInfo(ref DataSet dtSet);
    }

    public class DBAccessHandler: DBFunctions
    {
        DB dbase;
        DBTYPE dbType;
        public DBAccessHandler(DBTYPE dbtype)
        {
            this.dbType = dbtype;
            switch (this.dbType)
            {
                case DBTYPE.MYSQL:
                    dbase = new MySQLDB();
                    break;
                default:
                    // fall back to your default db
                    break;
            }
        }

        public void getUserInfo(ref DataSet dtSet)
        {
            String query = "SELECT id,name FROM info";
            dbase.fillDataSet(ref dtSet, query, "info");
        }

        public void getUserDetailedInfo(ref DataSet dtSet)
        {
            String query = "SELECT id,email FROM detail_info";
            dbase.fillDataSet(ref dtSet, query, "d_info");
        }
    }
These classes are so basic. There is not much to discuss. The two main points are the name of the datatable used in calling the fillDataSet. We will create same named datatable inside a dataset. Now we are done implementing our database implementation source file. Now we will move to the Windows form application.
I have created a very basic user interface just like the picture below -
Now we will make a dataset which will represent the database we are using. This dataset will be our transparent disconnected database. The dataset will look like below - 
As you can see that, the name of the datatable matches with the implemented interface function in DBAccessHandler class.
Now the codes -

public partial class Form1 : Form
    {
        public ComboBox ComboName { get { return _comboName; } }
        public ComboBox ComboEmail { get { return _comboEmail; } }
        private DBAccess.DBAccessHandler dbHandler = null;
        private DtSet dtSet = null;
        public Form1()
        {
            InitializeComponent();
            dbHandler = new DBAccessHandler(DBTYPE.MYSQL);
            dtSet = new DtSet();
            GetDatas();
            FillComboBox();
            SetupHandlers();
        }

        private void SetupHandlers()
        {
            ComboName.SelectedIndexChanged += new EventHandler(ComboName_SelectedIndexChanged);
        }

        void ComboName_SelectedIndexChanged(object sender, EventArgs e)
        {
            DataView tempView = dtSet.Tables[1].DefaultView;
            tempView.RowFilter = String.Format("id={0}", (int)((ComboBox)sender).SelectedValue);
            ComboEmail.DataSource = tempView;
            ComboEmail.DisplayMember = "email";
        }

        private void FillComboBox()
        {
            ComboName.DataSource = dtSet;
            ComboName.DisplayMember = "info.name";
            ComboName.ValueMember = "info.id";
        }

        private void GetDatas()
        {
            DataSet tempDtSet = (DataSet)dtSet;
            dbHandler.getUserInfo(ref tempDtSet);
            dbHandler.getUserDetailedInfo(ref tempDtSet);
        }

    }
 As you can see that inside the GetDatas function we called our database functions which handles the MySQL native query for this methods. After we populate data in the dataset we set ComboName combobox's datasource as that dataset. Now our dataset acts as the transparent database. We have access to detached database through it. 

The DisplayMember property tells which member of the datatable to be displayed & the ValueMember property let us map a value against the currently displaying DisplayMember. In this way we will get the associated id against a name easily.

Next we registered the selectedindexchanged event and add a filter based on the current selected value (i,e id of the name) and make a new dataview from the existing datatable. We then sets this dataview in the ComboEmail.
Hope this tutorial gives you an idea of how to use the ADO.NET. If you have any suggestion or query please leave a comment. 

Source Code.

Wednesday, May 18, 2011

ADO.NET - Microsoft's Data Abstraction Architecture

What an application do in a computer? It plays with data, data & data using logic. And databases are versatile storage for the data. Application talks to the database to get the desired data quickly. One application can talk to Oracle database, another may talk to MySQL. The communication system between these db is db specific.

These leads us to a common question, isn't it possible to implement an architecture which can talk to any db with minimum implementation & logic level transparency? It was possible via JDBC. Now it is possible through C#/VB using .Net framework. ADO.NET is the Microsoft's implementation similar to JDBC, but with some great features. The main backbone of ADO.NET is the DataSet, DataTable & DataAdapter. ADO.NET architecture looks like this -


As you can see that the Data Provider provides database specific implementation. DataSet & DataTable grants the application a transparent view of the database.

Data Provider consist of Connection, Command & DataReader. IdbConnection, IdbCommand & IdbDataReader provides interfaces to implement database specific Connection, Command & DataReader. The Connection is responsible for connecting to the specific db. Command takes the query to execute against an open Connection & sets up the parameter of the query. DataReader is responsible to read the returned value from the database after executing the Command.

Now DataSet, DataTable & DataAdapter comes into play. DataAdapter is a provider which can create DataSet on the fly. It uses database specific Connection & Command to execute a query against the database and creates the transparent database DataSet on the fly. DataSet can hold many DataTable. These DataTables are the logical representation of database tables. After creating the DataSet, application use the DataSet as the database itself. Thus ADO.NET provides the logic level transparency.

DataSet is also used for RAD. If you know what will be the content of a DataTable inside a DataSet you can design that DataTable graphically and the attach it to a controller. This way you create a forward declaration to your DataTable content & can leverage that information to build application more quickly.

Another great power of ADO.NET is the XML / LINQ. You can use XML input as database.

Hope this article gives you an overview on ADO.NET architecture. If you have any query or suggestion please fill free to leave a comment. Next time I will try to give demonstrate a sample program using ADO.NET.
Till then, goodbye. :)

Sunday, May 1, 2011

Desiging your way to Implementation

Many young developer has a liking to solve a problem brute forcibly rather than solving it elegantly. From SDLC we know that Designing a system takes much time rather than implementing the system. Yet many developer just jumped into implementing the solution without designing the whole system in first place. Many developer design and develop at the same time without knowing the upcoming risks they may incur. A bad designed solution will not stay in the long run.




The brute force approach has a benefit. If a problem is small and does not required to be maintained in future then brute force approach save time. But whenever it is a long term project then the fruit of a good design starts to come. Good designed solutions always have a room for future improvement. The maintainability is one of the major benefits.

Though I am a very new developer but I have worked with some excellent senior people in my company. And I learned from them & also by participating in design phase of some solutions. Today I am gonna share my experience & thought on design with you -

1. Decoupled modules: While designing a solution always try to decouple the modules. decoupled modules can work independently. Which enables the developer to modify the specific module without worrying about the whole system. If someone to change an implementation within a module, he/she doesn't have to concern about the interactions with other modules.

2. Minimize the expose of Class implementation: Try to minimize the details of the class implementation. Because if you use too much implementation details of a class then changing the class will seriously increase development time. Say In one class A, we are using B's x property which is a integer type. Now for some requirement we need to change the property type from integer to char. In this scenario, if we previously used that statement 1000 times then we have to change the code manually in 1000 places.

3. Revise & Revise: Over and over revise your design to check if there is room for improvement and try to clear out the design flaws. The sooner you can cancel out the bugs the better and extensible solution you will make.

4. Do not think about implementation details when design, think about the requirement and solution: Well I think this is a common mistake we made while designing. Implementation depends on design. But while designing you should never think about implementation details. You should think about the requirement & solution while designing because you are trying to make the solution a better one not the implementation of a certain solution better.

5. Trade & Decisions: Design is somewhat making trades and decision. Choosing the better decision is a matter of requirement & situation. But never rule out a decision as bad because what is a bad decision in one context will be the best in another context. Choosing wisely the trade-offs will surely prove to be useful later.

I think that's about it. I am not in a position to defend that my concept about the design is totally right. But it is what I have learned from my seniors. If you think some of them are wrong, please feel free to comment. Because through decision may be I can improve my concept of designing.

Happy designing.