DB Agnostic ASP.Net? - c#

we are making an ASP.Net application. We would like to have our application to be at least sorta DB agnostic, most notable to be compatible with both SQL Server and PostgreSQL. What is the best way of doing this? What are some of the common pitfalls? Also is there a class or something that already abstracts away the difference between things like SqlConnection and whatever PostgreSQL uses for connections?
(We are wanting to be DB agnostic so we can use PostgreSQL here(in development and later in our own hosting) due to price and let our self-hosting clients use Sql Server if they so wish)

All ADO.Net providers extend the basic interfaces:
IDbConnection
IDbTransaction
IDbCommand
IDataReader
IDbDataParameter
So in theory you can write your whole DAL (Data Access Layer) against the abstract interfaces and leverage any provider, including 3rd party ones like MySQLs. In practice, no mortal ever managed to pull this trick. The interfaces are very hard to program against on one hand, and any application beyond a demo-ware will quickly run into the wall of SQL dialects incompatibility.
A more feasable approach is to settle for a number of target destinations and develope specific DALs. Entity Framework and repository pattern and nHibernate and all such help, but none solves the fundamental issues.

You could use Entity Framework. That way you would have a single programming model to work against.
http://msdn.microsoft.com/en-us/library/aa697427(VS.80).aspx
http://www.devart.com/dotconnect/postgresql/

If you just want to use ADO.NET directly, you can use the DbProviderFactory to abstract away the provider (SqlClient, OleDb etc) that you are using. Usually you use this in conjunction with the <connectionStrings> configuration element, with code something like:
ConnectionStringSettings c = ConfigurationManager.ConnectionStrings[name];
DbProviderFactory factory = DbProviderFactories.GetFactory(c.ProviderName)
...
IDbConnection connection = _factory.CreateConnection();
connection.ConnectionString = c.ConnectionString;
...
There's lots of info in MSDN.
Of course this doesn't help you with differences in SQL syntax between different providers - you need a lowest common denominator approach to work with multiple providers. This affects things like the syntax for parameters (e.g. # prefix for SQL Server, positional parameters only for OleDb, ...).

I just create an interface for my data source and then implement it for each data source type I need to use. Normally they look something like this:
public interface IMyProjectDataSource
{
IEnumerable<string> GetUserNames();
void AddUser(string userName);
}
public class SqlServerMyProjectDataSource : IMyProjectDataSource
{
public SqlServerMyProjectDataSource(string connectionString)
{
//...
}
public IEnumerable<string> GetUserNames()
{
//...
}
public void AddUser(string userName)
{
//...
}
}
public class PostgreSqlMyProjectDataSource : IMyProjectDataSource
{
public IEnumerable<string> GetUserNames()
{
//...
}
public void AddUser(string userName)
{
//...
}
}
public class HttpCacheSqlMyProjectDataSource : IMyProjectDataSource
{
public HttpCacheSqlMyProjectDataSource(IMyProjectDataSource parentMyProjectDataSource)
{
}
public IEnumerable<string> GetUserNames()
{
//...
}
public void AddUser(string userName)
{
//...
}
}
I also like this because it allows you to "chain" them together. For instance you can do all of your data source caching like this:
public class HttpCacheSqlMyProjectDataSource : IMyProjectDataSource
{
public HttpCacheSqlMyProjectDataSource(IMyProjectDataSource parentMyProjectDataSource)
{
//...
}
public IEnumerable<string> GetUserNames()
{
//...
}
public void AddUser(string userName)
{
//...
}
}
The hardest part is deciding how to create it, especially if you're planning to chain more than one together. For that I generally store it in my Global.asax.cs as a singleton and create it from a type name in the .config file. You can use Type.GetType() and then Activator.CreateInstance() to do that and most of the chaining I have will be done no matter what the data source in the .config is so I don't have to worry about creating some sort of "constructor" type or a complicated .config.
Hopefully that makes sense. This may not be the best for all situations but I have had a lot of luck with it.

Entity Framework is an option as mentioned by Shiraz. You might also consider other ORM solutions such as NHibernate.

I would recommend to go with some sort of Repository Pattern.
It's not a silver bullet that will save you from hacking for each DBMS flavour, but that is the way to go if you want it to be maintainable from the beginning, something that ORMs just do not provide.
http://blog.wekeroad.com/2008/04/07/asp-net-mvc-mvc-storefront-part-2

At a very high level you would want to use something that abstracts your database more than just the SqlConnection, SqlCommand, and Sql* classes. So when people say to use ORMs, they're pretty much right. The ORMs provide that level of abstraction for you.
But for abstracting away SqlCommand and SqlConnection there are interfaces in the System.Data namespace. IDbConnection, IDbCommand, etc. are already inside the framework and you can code against those. The issue then is finding kind of way to create the concrete classes and you can tackle that using an IoC container or a provider pattern.

The best solution for database-agnostic applications is usually an ORM (this tag). There are plenty of them for .NET - this question will give you some guidance on which one to choose.
The three most popular ones are:
NHibernate
Linq-to-SQL (now superceded by Entity Framework) - used by Stackoverflow.com. SQL Server only
Subsonic

Related

C# work with database which type is not known in advance

I have an app that collects data and writes it to a database. The database type is not known in advance, it's defined via an .ini file. So I have a method like this, if the database is Firebird SQL:
public bool writeToDB()
{
FbConnection dbConn = new FbConnection(connString);
dbConn.Open();
FbTransaction dbTrans = dbConn.BeginTransaction();
FbCommand writeCmd = new FbCommand(cmdText, dbConn, dbTrans);
/* some stuff */
writeCmd.ExecuteNonQuery();
dbTrans.Commit();
writeCmd.Dispose();
dbConn.Close();
return true;
}
To make the same work for e.g. MS Access database, I only have to replace FbConnection, FbTransaction and FbCommand with OleDbConnection, OleDbTransaction and OleDbCommand respectively.
But I don't want to have a separate identical method for each type of database.
Is it possible to define the database connection / transaction / command type at runtime, after the database type is known?
Thanks
When you're writing code at this level - opening and closing connections, creating and executing commands - there's probably no benefit in trying to make this method or class database-agnostic. This code is about implementation details so it makes sense that it would be specific to an implementation like a particular database.
But I don't want to have a separate identical method for each type of database.
You're almost certainly better off having separate code for separate implementations. If you try to write code that accommodates multiple implementations it will be complicated. Then another implementation (database) comes along which almost but doesn't quite fit the pattern you've created and you have to make it even more complicated to fit that one in.
I don't know the specifics of what you're building, but "what if I need a different database" is usually a "what if" that never happens. When we try to write one piece of code that satisfies requirements we don't actually have, it becomes complex and brittle. Then real requirements come along and they're harder to meet because our code is tied in knots to do things it doesn't really need to do.
That doesn't mean that all of our code should be coupled to a specific implementation, like a database. We just have to find a level of abstraction that's good enough. Does our application need to interact with a database to save and retrieve data? A common abstraction for that is a repository. In C# we could define an interface like this:
public interface IFooRepository
{
Task<Foo> GetFoo(Guid fooId);
Task Save(Foo foo);
}
Then we can create separate implementations for different databases if and when we need them. Code that depends on IFooRepository won't be coupled to any of those implementations, and those implementations won't be coupled to each other.
First (and Second and Third). STOP REINVENTING THE WHEEL.
https://learn.microsoft.com/en-us/ef/core/providers/?tabs=dotnet-core-cli
Alot of code and an alot of better testing has already been done.
Guess what is in that larger list:
FirebirdSql.EntityFrameworkCore.Firebird Firebird 3.0 onwards
EntityFrameworkCore.Jet Microsoft Access files
......
So I'm gonna suggest something in lines with everyone else. BUT also... allows for some reuse.
I am basing this .. on the fact the Entity Framework Core...provides functionality to several RDBMS.
See:
https://learn.microsoft.com/en-us/ef/core/providers/?tabs=dotnet-core-cli
public interface IEmployeeDomainDataLayer
{
Task<Employee> GetSingle(Guid empKey);
Task Save(Employee emp);
}
public abstract class EmployeeEntityFrameworkDomainDataLayerBase : IEmployeeDomainDataLayer
{
/* you'll inject a MyDbContext into this class */
//implement Task<Employee> GetSingle(Guid empKey); /* but also allow this to be overrideable */
//implement Task Save(Employee emp); /* but also allow this to be overrideable */
}
public class EmployeeJetEntityFrameworkDomainDataLayer : EmployeeEntityFrameworkDomainDataLayerBase, IEmployeeDomainDataLayer
{
/* do not do any overriding OR override if you get into a jam */
}
public class EmployeeSqlServerEntityFrameworkDomainDataLayer : EmployeeEntityFrameworkDomainDataLayerBase, IEmployeeDomainDataLayer
{
/* do not do any overriding OR override if you get into a jam */
}
You "code to an interface, not an implementation". Aka, your business layer codes to IEmployeeDomainDataLayer.
This gives you most code in EmployeeEntityFrameworkDomainDataLayerBase. BUT if any of the concretes give you trouble, you have a way to code something up ONLY FOR THAT CONCRETE.
If you want DESIGN TIME "picking of the RDBMS", then you do this:
You inject one of the concretes ( EmployeeJetEntityFrameworkDomainDataLayer OR EmployeeSqlServerEntityFrameworkDomainDataLayer ) into your IOC, based on which backend you want to wire to.
If you want RUN-TIME "picking of the RDMBS", you can define a "factory".
public static class HardCodedEmployeeDomainDataLayerFactory
{
public static IEmployeeDomainDataLayer getAnIEmployeeDomainDataLayer(string key)
{
return new EmployeeJetEntityFrameworkDomainDataLayer();
// OR (based on key)
return new EmployeeSqlServerEntityFrameworkDomainDataLayer();
}
}
The factory above suffers from IOC anemia. Aka, if your concretes need items for their constructors..you have to fudge them.
A better idea of the above is the kissing cousin of "Factory" pattern, called the Strategy Design.
It is a "kinda factory", BUT you inject the possible results of the "factory" in via a constructor. Aka, the "factory" is NOT hard coded...and does NOT suffer from IOC anemia.
See my answer here:
Using a Strategy and Factory Pattern with Dependency Injection

C# WPF MVVM change between multiple database connection types

I'm prepering for my final exam with C# WPF using MVVM creating an query editor which needs to support multiple database motors, and wondering what's the best practice of having multiple database connection types to switch between in a view.
This includes having etc. oracle, mssql, mysql connections.
I thought of two scenarios to do this which is:
A) Create a new instance of a database connection, where it creates a new view window to display so the user can work for that specifik connection.
B) Make a global access list to switch between connections by written command. etc. 'change database to xxxx', for the current view they are displaying.
What i'm searching for, is scenario B), so it's more flexible for the user. I'm so far being guided to read about dependency injection and inheritance, where it delegating from abstract baseclass to resolve this.
The second thing is how to access this list afterwards in the command field, find the name of a database based on the database name written, and change the connection type for the (this) current view they are displaying. But, this needs to be unique due we cannot hard-code the connection type in any viewModels.
Currently i'm guided using DataServices, with MVVMLight nuget, where it's created one per connection type. Here i store the connection in one list:
public class MySqlService : IMySqlService
{
private List<MySqlConnection> Connections = new List<MySqlConnection>();
public MySqlConnection AddConnection(string hostName, string userName, string userPassword, string dataBase)
{
var connectionString = $"Server={hostName};database={dataBase};user id={userName};password={userPassword};";
var mySqlCon = new MySqlConnection(connectionString);
if(mySqlCon.State == ConnectionState.Closed)
{
mySqlCon.Open();
Connections.Add(mySqlCon);
return mySqlCon;
}
else
{
return null;
}
}
Result case
I've found an described response on Stack.Exchange site which has below response, in case it gets removed:
Short:
What you want is multiple implementations for the interface that your application uses.
like so:
public interface IDatabase
{
void SaveToDatabase();
void ReadFromDatabase();
}
public class MySQLDatabase : IDatabase
{
public MySQLDatabase ()
{
//init stuff
}
public void SaveToDatabase(){
//MySql implementation
}
public void ReadFromDatabase(){
//MySql implementation
}
}
public class SQLLiteDatabase : IDatabase
{
public SQLLiteDatabase ()
{
//init stuff
}
public void SaveToDatabase(){
//SQLLite implementation
}
public void ReadFromDatabase(){
//SQLLite implementation
}
}
//Application
public class Foo {
public IDatabase db = GetDatabase();
public void SaveData(){
db.SaveToDatabase();
}
private IDatabase GetDatabase()
{
if(/*some way to tell if should use MySql*/)
return new MySQLDatabase();
else if(/*some way to tell if should use MySql*/)
return new SQLLiteDatabase();
throw new Exception("You forgot to configure the database!");
}
}
As far as a better way of setting up the correct IDatabase implementation at run time in your application, you should look into things like "Factory Method", and "Dependancy Injection".
Long:
This question, especially in the database context, has been asked too many times. Here I will try to thoroughly show you the benefit of using abstraction (using interfaces) to make your application less coupled and more versatile.
Before reading further, I recommend you to read and get a basic understanding of Dependency injection, if you do not know it yet. You might also want to check the Adapter design pattern, which is basically what hiding implementation details behind interface's public methods means.
Dependency injection, coupled with Factory design pattern, is the foundation stone and an easy way to code the Strategy design pattern, which is a part of IoC principle.
Don't call us, we will call you. (AKA the Hollywood principle).
Decoupling an application using abstraction
1. Making the abstraction layer
You create an interface - or abstract class, if you are coding in a language like C++ - and add generic methods to this interface. Because both interfaces and abstract classes have the behaviour of you not being able to use them directly, but you have to either implement (in case of interface) or extend (in case of abstract class) them, the code itself already suggests, you will need to have specific implementations to fullfil the contract given by either the interface or the abstract class.
Your (very simple example) database interface might look like this (the DatabaseResult or DbQuery classes respectively would be your own implementations representing database operations):
public interface Database
{
DatabaseResult DoQuery(DbQuery query);
void BeginTransaction();
void RollbackTransaction();
void CommitTransaction();
bool IsInTransaction();
}
Because this is an interface, it itself does not really do anything. So you need a class to implement this interface.
public class MyMySQLDatabase : Database
{
private readonly CSharpMySQLDriver _mySQLDriver;
public MyMySQLDatabase(CSharpMySQLDriver mySQLDriver)
{
_mySQLDriver = mySQLDriver;
}
public DatabaseResult DoQuery(DbQuery query)
{
// This is a place where you will use _mySQLDriver to handle the DbQuery
}
public void BeginTransaction()
{
// This is a place where you will use _mySQLDriver to begin transaction
}
public void RollbackTransaction()
{
// This is a place where you will use _mySQLDriver to rollback transaction
}
public void CommitTransaction()
{
// This is a place where you will use _mySQLDriver to commit transaction
}
public bool IsInTransaction()
{
// This is a place where you will use _mySQLDriver to check, whether you are in a transaction
}
}
Now you have a class which implements the Database, the interface just became useful.
2. Using the abstraction layer
Somewhere in your application, you have a method, let's call the method SecretMethod, just for fun, and inside this method you have to use the database, because you want to fetch some data.
Now you have an interface, which you cannot create directly (uh, how do I use it then), but you have a class MyMySQLDatabase, which may be constructed using the new keyword.
GREAT! I want to use a database, so I will use the MyMySQLDatabase.
Your method might look like this:
public void SecretMethod()
{
var database = new MyMySQLDatabase(new CSharpMySQLDriver());
// you will use the database here, which has the DoQuery,
// BeginTransaction, RollbackTransaction and CommitTransaction methods
}
This is not good. You are directly creating a class inside this method, and if you are doing it inside the SecretMethod, it is safe to assume you would be doing the same in 30 other methods. If you wanted to change the MyMySQLDatabase to a different class, such as MyPostgreSQLDatabase, you would have to change it in all your 30 methods.
Another problem is, if the creation of MyMySQLDatabase failed, the method would never finish and therefore would be invalid.
We start by refactoring the creation of the MyMySQLDatabase by passing it as a parameter to the method (this is called dependency injection).
public void SecretMethod(MyMySQLDatabase database)
{
// use the database here
}
This solves you the problem, that the MyMySQLDatabase object could never be created. Because the SecretMethod expects a valid MyMySQLDatabase object, if something happened and the object would never be passed to it, the method would never run. And that is totally fine.
In some applications this might be enough. You may be satisfied, but let's refactor it to be even better.
The purpose of another refactoring
You can see, right now the SecretMethod uses a MyMySQLDatabase object. Let's assume you moved from MySQL to MSSQL. You do not really feel like changing all the logic inside your SecretMethod, a method which calls a BeginTransaction and CommitTransaction methods on the database variable passed as a parameter, so you create a new class MyMSSQLDatabase, which will also have the BeginTransaction and CommitTransaction methods.
Then you go ahead and change the declaration of SecretMethod to the following.
public void SecretMethod(MyMSSQLDatabase database)
{
// use the database here
}
And because the classes MyMSSQLDatabase and MyMySQLDatabase have the same methods, you do not need to change anything else and it will still work.
Oh wait!
You have a Database interface, which the MyMySQLDatabase implements, you also have the MyMSSQLDatabase class, which has exactly the same methods as MyMySQLDatabase, perhaps the MSSQL driver could also implement the Database interface, so you add it to the definition.
public class MyMSSQLDatabase : Database { }
But what if I, in the future, don't want to use the MyMSSQLDatabase anymore, because I switched to PostgreSQL? I would have to, again, replace the definition of the SecretMethod?
Yes, you would. And that does not sound right. Right now we know, that MyMSSQLDatabase and MyMySQLDatabase have the same methods and both implement the Database interface. So you refactor the SecretMethod to look like this.
public void SecretMethod(Database database)
{
// use the database here
}
Notice, how the SecretMethod no longer knows, whether you are using MySQL, MSSQL or PotgreSQL. It knows it uses a database, but does not care about the specific implementation.
Now if you wanted to create your new database driver, for PostgreSQL for example, you won't need to change the SecretMethod at all. You will make a MyPostgreSQLDatabase, make it implement the Database interface and once you are done coding the PostgreSQL driver and it works, you will create its instance and inject it into the SecretMethod.
3. Obtaining the desired implementation of Database
You still have to decide, before calling the SecretMethod, which implementation of the Database interface you want (whether it is MySQL, MSSQL or PostgreSQL). For this, you can use the factory design pattern.
public class DatabaseFactory
{
private Config _config;
public DatabaseFactory(Config config)
{
_config = config;
}
public Database getDatabase()
{
var databaseType = _config.GetDatabaseType();
Database database = null;
switch (databaseType)
{
case DatabaseEnum.MySQL:
database = new MyMySQLDatabase(new CSharpMySQLDriver());
break;
case DatabaseEnum.MSSQL:
database = new MyMSSQLDatabase(new CSharpMSSQLDriver());
break;
case DatabaseEnum.PostgreSQL:
database = new MyPostgreSQLDatabase(new CSharpPostgreSQLDriver());
break;
default:
throw new DatabaseDriverNotImplementedException();
break;
}
return database;
}
}
The factory, as you can see, knows which database type to use from a config file (again, the Config class may be your own implementation).
Ideally, you will have the DatabaseFactory inside your dependency injection container. Your process then may look like this.
public class ProcessWhichCallsTheSecretMethod
{
private DIContainer _di;
private ClassWithSecretMethod _secret;
public ProcessWhichCallsTheSecretMethod(DIContainer di, ClassWithSecretMethod secret)
{
_di = di;
_secret = secret;
}
public void TheProcessMethod()
{
Database database = _di.Factories.DatabaseFactory.getDatabase();
_secret.SecretMethod(database);
}
}
Look, how nowhere in the process you are creating a specific database type. Not only that, you aren't creating anything at all. You are calling a GetDatabase method on the DatabaseFactory object stored inside your dependency injection container (the _di variable), a method, which will return you the correct instance of Database interface, based on your configuration.
If, after 3 weeks of using PostgreSQL, you want to go back to MySQL, you open a single configuration file and change the value of DatabaseDriver field from DatabaseEnum.PostgreSQL to DatabaseEnum.MySQL. And you are done. Suddenly the rest of your application correctly uses the MySQL again, by changing one single line.
Best practice is that you simply don't dynamically change database type.
In real world apps you don't really dynamically change between oracle and sql server or mysql. Your data is in a given database and that's where it's staying. It's a big deal changing to another one and that will necessitate porting data, staff learning the new rdbms, quite possibly rewriting swathes of stored procedures.
Some software packages are intended to support multiple different rdbms but this is a one off decision that is taken prior to install.
One client has sql server and that's what they want to use. Another client has Oracle so that's what they expect to use.
There are exceptions, of course.
A client might want your small system to be installed locally and keep costs down by using a free rdbms like sql express.
One off install choices are often supported.
When designing such a system it is usual to try and minimise what needs to be switched out.
This is not always possible.
For simple systems it can sometimes be "just" a matter of a connection string to change and this is handled by config file.
Others have more complicated requirements and the tendency then is to encapsulate within stored procedures if possible. That way your code can remain the same but Oracle has a stored procedure which does oracle specific stuff and the sql server database has a stored procedure does sql server specific stuff. This means writing, testing and optimising stored procedures for each option. Which is costly and far from ideal. There is an "up" side though. If the client company has a DBA, they can potentially tweak your stored procedures for performance.

Decoupled architecture

I'm working on a system where I'd like to have my layers decoupled as much as possible, you know, some kind of modular application to be able to switch databases and stuff without a serious modification of the rest of the system.
So, I've been watching for x-the time one of the talks of Robert C. Martin about good practices, clean code, decoupling architecture etc, to get some inspiration. What I find kinda weird is his description of the system Fitnesse and the way they've implemented store/load methods for WikiPages. I'm linking the video as well: Robert C. Martin - Clean Architecture and Design
What's he describing (at least from my understanding) is that the entity is aware of the mechanism how to store and load itself from some persistent layer. When he wanted to store WikiPages in-memory, he simply overrode the WikiPage and created a new InMemoryWikiPage. When he wanted to store them in a database, he did the same thing...
So, one of my questions is - what is this approach called? I've been learning the whole time about Repository patterns and stuff, and why should be classes like this persistence-ignorant, but I can't seem to find any materials on this thing he did. Because my application will consist of modules, I think this may help to solve my problems without a need for creating some centralized store for my entities... Every module would simply take care of itself including persistence of its entities.
I think the code would look like is something like this:
public class Person : IEntity
{
public int ID { get;set; }
public string Name { get;set; }
public void Save()
{
..
}
public void Update()
{
}
public void Delete()
{
}
...
}
Seems a bit weird, but... Or maybe I misunderstood what he said in the video?
My second question would be, if you don't agree with this approach, what would be the path you'd take in such modular application?
Please provide an example if possible with some explanation.
I'll answer your second question. I think you will be interested as well in Dependency Injection.
I'm not an expert on DI but I'll try to explain as clear as I'm able to.
First off, from wikipedia:
Dependency injection is a software design pattern that allows removing hard-coded dependencies and making it possible to change them, whether at run-time or compile-time.
The primary purpose of the dependency injection pattern is to allow selection among multiple implementations of a given dependency interface at runtime, or via configuration files, instead of at compile time.
There are many libraries around that help you implement this design pattern: AutoFac, SimpleInjector, Ninject, Spring .NET, and many others.
In theory, this is what your code would look like (AutoFac example)
var containerBuilder = new ContainerBuilder();
//This is your container builder. It will be used to register interfaces
// with concrete implementations
Then, you register concrete implementations for interface types:
containerBuilder.RegisterType<MockDatabase>().As<IDatabase>().InstancePerDependency();
containerBuilder.RegisterType<Person>().As<IPerson>().InstancePerDependency();
In this case, InstancePerDependency means that whenever you try to resolve IPerson, you'll get a new instance. It could be for example SingleInstance, so whenever you tried to resolve IPerson, you would get the same shared instance.
Then you build your container, and use it:
var container = containerBuilder.Build();
IPerson myPerson = container.Resolve<IPerson>(); //This will retrieve the object based on whatever implementation you registered for IPerson
myPerson.Id = 1;
myPerson.Save(); //Save your changes
The model I used in this example:
interface IEntity
{
int Id { get; set; }
string TableName { get; }
//etc
}
interface IPerson: IEntity
{
void Save();
}
interface IDatabase
{
void Save(IEntity entity);
}
class SQLDatabase : IDatabase
{
public void Save(IEntity entity)
{
//Your sql execution (very simplified)
//yada yada INSERT INTO entity.TableName VALUES (entity.Id)
//If you use EntityFramework it will be even easier
}
}
class MockDatabase : IDatabase
{
public void Save(IEntity entity)
{
return;
}
}
class Person : IPerson
{
IDatabase _database;
public Person(IDatabase database)
{
this._database = database;
}
public void Save()
{
_database.Save(this);
}
public int Id
{
get;
set;
}
public string TableName
{
get { return "Person"; }
}
}
Don't worry, AutoFac will automatically resolve any Person Dependencies, such as IDatabase.
This way, in case you wanted to switch your database, you could simply do this:
containerBuilder.RegisterType<SqlDatabase>().As<IDatabase>().InstancePerDependency();
I wrote an over simplified (not suitable for use) code which serves just as a kickstart, google "Dependency Injection" for further information. I hope this helps. Good luck.
The pattern you posted is an Active Record.
The difference between Repository and Active Record Pattern is that in Active Record pattern, data query and persistence, and the domain object are in one class, where as in Repository, the data persistence and query are decoupled from the domain object itself.
Another pattern that you may want to look into is the Query Object which, unlike respository pattern where its number of methods will increase in every possible query (filter, sorting, grouping, etc) the query object can use fluent interface to be expressive [1] or dedicated in which one you may pass parameter [2]
Lastly, you may look at Command Query Responsibility Segregation architecture for ideas. I personally loosely followed it, just picked up ideas that can help me.
Hope this helps.
Update base on comment
One variation of Repository pattern is this
UserRepository
{
IEnumerable<User> GetAllUsers()
IEnumerable<User> GetAllByStatus(Status status)
User GetUserById(int id)
...
}
This one does not scale since the repository get's updated for additional query that way be requested
Another variation is to pass query object as parameter to the data query
UserRepository
{
IEnumerable<User> GetAll(QueryObject)
User GetUserById(int id)
...
}
var query = new UserQueryObject(status: Status.Single)
var singleUsers = userRepo.GetAll(query)
Some in .Net world, Linq expression is passed instead of QueryObject
var singleUsers = userRepo.GetAll(user => user.Status == Status.Single)
Another variation is to do dedicate Repository for retrieval on one entity by its unique identifier and save it, while query object is used to submit data retrieval, just like in CQRS.
Update 2
I suggest you get familiar with the SOLID principles. These principles are very helpful in guiding you creating a loosely coupled, high cohesive architecture.
Los Techies compilation on SOLID pricples contains good introductory articles regarding SOLID priciples.

C# Design Pattern for Database Helper classes

I'm designing a WCF Service that will called by several hundred clients, and I have a question about the best architecture for the classes that will run by database queries. Today I only access SQL Server, so I have a static class that I call internally that does all the dirty work of creating connections and datareaders. Below is a simple example:
namespace DBHelper.Utility
{
public static class SqlDBManager
{
public static void RunSql(String pSql, DBParamsHelper pDBParams, String pConnStringConfigName)
{
String sConnectionString = GetConnectionStringFromConfig(pConnStringConfigName);
SqlConnection oConn = new SqlConnectionsConnectionString
oConn.Open();
try
{
SqlCommand oCommand = new SqlCommand(pSql, oConn);
oCommand.CommandTimeout = 0;
if (pDBManagerParams != null)
{
foreach (SqlParameter sqlParam in pDBManagerParams)
{
oCommand.Parameters.Add(sqlParam);
}
}
oCommand.ExecuteNonQuery();
}
finally
{
oConn.Close();
}
}
}
}
Now, I need to add support for running both Sql Server and Oracle. My initial idea was to declare an interface, and have my existing SqlDBManager implement it, and then develop an OracleDBManager implementing the same interface. The problem is that my class is static, and static classes cannot implement an interface. I would like my helper class to remain as static, with it's a lot more practical, and I don't have to create a new object every time I need to run a query. I also thought of using class inheritance, but I can't have statis virtual methods, so not much use there. I considered some singleton implementations so I wouldn't have to create classes, but then I would have trouble on the multi-threaded access.
What would be the best design pattern so I can have great performance on multiple threaded scenario (very important), not too much work coding for productivity (not have to create a lot of classes), and have a standard methods for both OracleDBManager and SqlDBManager classes? The standard method is very important, because I don't want to the code that uses these helper classes to know if they are connected to Oracle or Sql Server.
I did consider using ORM solution, such as Entity Framework 4 and nHibernate, but the performance impact was too much. Since I will run simple queries, the query syntax difference between PL-SQL and TSQL won't matter.
Any input and idea will be greatly appreciated. Tks
Why not make your static method private, wrap the classes in an interface to support MS-SQL / Oracle, and call the private static methods in the respective interfaces?
E.g:
public interface ISqlDbManager
{
void SaveOrder(Order o);
void FindOrderById(int orderId);
}
public class SqlServerDbManager : ISqlDbManager
{
private static void RunSql(String pSql, DBParamsHelper pDBParams, String pConnStringConfigName)
{
// implement as you did above
}
public void FindOrderById(int orderId)
{
// create SQL, call private "RunSql" method.
}
}
Do the same thing for the other implementation (OracleDbManager).
It makes sense to have it private, since the consumer shouldn't care how the underlying persistence mechanism works.
And this will also make unit testing easier - create a "MockDbManager" class, where the private static method does basic LINQ operations on an in-memory list.
On a side note, i would strongly recommend the use of stored procedures, instead of constructing sql commands manually. Better for query plan caching / optimization.
The interface is the right direction to go in, but as you've pointed out, you can't have a static class implement an interface. I understand wanting to minimize the fuss of object creation, but that will likely be necessary in some way in order to have two different database classes.
The solution I suggest is multi-faceted. First is an interface with a signature similar to what you listed above:
public Interface IDbManager {
void RunSql(String pSql, DBParamsHelper pDBParams, String pConnStringConfigName)
}
That can be implemented in SQL- and Oracle-specific versions, you already have the SQL version, just make it non-static and implement the interface.
Now try a database factory, perhaps like the following:
public static class DbFactory {
public static IDbManager CreateDb(DbType type) {
select (type) {
case DbType.Sql:
return new SqlDbManager();
break;
case DbType.Sql:
return new OracleDbManager();
break;
}
}
}
Then you should be able to do something like:
var db = DbFactory.CreateDb(DbType.Sql);
db.RunQuery(...);
This code is untested, but hopefully you get the idea. I use a similar solution for one of my projects where I need to get data from different data stores. The strategy and factory patterns ease this process.
Hope that helps!

Refactoring the use of SqlConnection more than once in 1 class

I have some code which forms a database-centric class which performs CRUD operation. Insert() and Select() methods use the same connection string. At the moment, both methods are repetitive by repeating the standard bit of setting up a SqlConnection.
How best should this be refactored? Should I have a property for SqlConnection?
Thanks
Pull all your DB operations out into a single class, and pass the class to the objects that need it. You can do this via constructor injection (each new object gets an IDBProvider passed to it which it then uses for database operations).
Something like this:
public interface IDBProvider {
// ... list of DB operations you care about
List<Products> GetProducts(string vendor)
}
public class SomeWorkerClass {
private IDBProvider dbConnection;
public SomeWorkerClass(IDBProvider dbProvider) {
dbConnection = dbProvider;
}
public void SomeFunction() {
List<Products> = dbConnection.GetProducts("test");
}
}
There are lots of frameworks that do this kind of stuff for you, like NHibernate, but in some cases its just as easy to roll your own (upgrading existing code, organizations that dont want external framework dependencies, etc).
I usually do it one of two ways.
A class that contains static methods and properties to connect to a database. I can then use it in any other class I need.
A SqlConnection property in a class that connects to databases. I then inject the connection from the controlling class when I need it.
By far the first option is used most frequently. The only issue is that if the database server changes, I need to recompile the class. We only have one database server, though, and it doesn't change that often, so it really isn't that much of an issue.
The good thing about the second option is that it's a lot more flexible; if the server, user, or password changes it's as simple as updating that information in the controlling class.
This depends on your application. As far as I'm concerned: No. You might want to add a new method to set up the connection (that might even be a good idea), but a connection as field/property sounds like "I open a connection for the whole lifetime of my form", which is evil in my world.
Create a helper method and write something like
using (var connection = CreateSqlConnection()) {
// Do the operations here
}

Categories

Resources