My application's structure looks like this:
Solution: MySolution
Projects in MySolution: Host, Business, Server.
References between the projects looks like this:
Host <-- Business --> Server
(Business references Host and Server but Host does not reference Server and vice versa because this causes a circular-)
So, I have some Database stuff in Server. I have a property, DBConnectionString
- which should contain the connection string. What I want to do is to set this property from the Host but I want to keep all methods that have anything to do with the database in the Server project.
Keeping interfaces in mind - so that I can also at a later stage just create an web application.
I have some code and it's working but I don't know if this is the right way.
I have this interface in Library (connection between the other two projects):
public interface IDBUtils
{
string DBConnectionString { get; set; }
bool OpenConnection();
bool CloseConnection();
bool ExecuteSQL(string sql);
bool CreateDatabase(string servername, string databaseName, string databaseDataPath);
bool CreateDatabaseUser(string servername, string username, string password);
}
Then the class in Library that has the code for the interface:
public string DBConnectionString
{
get
{
return DBService.DB.DBUtils.DBConnectionString;
}
set
{
DBService.DB.DBUtils.DBConnectionString = value;
}
}
public bool OpenConnection()
{
return DBService.DB.DBUtils.OpenConnection();
}
public bool CloseConnection()
{
return DBService.DB.DBUtils.CloseConnection();
}
public bool ExecuteSQL(string sql)
{
return DBService.DB.DBUtils.ExecuteSQL(sql);
}
public bool CreateDatabase(string servername, string databaseName, string databaseDataPath)
{
return DBService.DB.DBUtils.CreateDatabase(servername, databaseName, databaseDataPath);
}
public bool CreateDatabaseUser(string servername, string username, string password)
{
return DBService.DB.DBUtils.CreateDatabaseUser(servername, username, password);
}
I'm only going to show the property and one method on the server otherwise this is going to get too long.
On the Server: Property:
public static string DBConnectionString { get; set; }
The OpenCOnnection() Method:
public static bool OpenConnection()
{
bool success = false;
try
{
if (DBConnectionString.Length > 0)
{
conn = new SqlConnection(DBConnectionString);
conn.Open();
success = true;
}
}
catch { /* Do nothing... */ }
return success;
}
To set the property from Host on Server:
It uses the interface on Library:
iDBUtils.DBConnectionString = connectionString.ToString();
To execute a method from Host on Server:
iDBUtils.OpenConnection();
So as you can see, Library is the "Middle Man".
2 Answers 2
Naming
IDBUtils
is a name for a namespace, but for an interface representing a database system it is poorly named. Better use something like IDatabase
, IDatabaseServer
or IDatabaseSystem
.
OpenConnection()
This method can be simplified by removing the success
variable and also using a guard clause, which reduces horizontal spacing.
public static bool OpenConnection()
{
if (String.IsNullOrWhiteSpace(DBConnectionString.Length))
{
return false;
}
try
{
conn = new SqlConnection(DBConnectionString);
conn.Open();
return true;
}
catch { /* Do nothing... */ }
return false;
}
Var
Use the var
keyword when defining local variables where the right hand side of the definition makes the type obvious. This looks cleaner and saves time when it comes to changing types during refactoring.
e.g.
bool success = false;
should be
var success = false;
Validation
You should validate the arguments to your public methods, any of those strings could be null or empty.
Catch { /* do nothing */ }
really swallowing everything that could go wrong with opening a connection? Imo that method should either succeed or blow up with something more meaningful than afalse
... \$\endgroup\$