Note: I DON't want to write custom membership provider.
I want to write my own Provider class so I can define it in web.config and access it like Membership class.
Here is a sample of my class (it has many other static methods):
public static class MySqlHelper
{
private static string constring = ConfigurationManager.ConnectionStrings["MyConnString"].ConnectionString;
public static int ExecuteNonQuery(string mysqlquery)
{
SqlConnection conn = new SqlConnection(connString);
SqlCommand cmd = new SqlCommand(mysqlquery, conn);
int result;
try
{
conn.Open();
result= cmd.ExecuteNonQuery();
}
finally
{
conn.Close();
}
return result;
}
}
Usage: MySqlHelper.ExecuteNonQuery("select * from customers");
Now as you see I have hard-coded the name of connectionstring i.e. "MyConnString". I am planning to make it dynamic.
So I was wondering if I can make it like static built-in Membership class, where I can define the connectionStringName in web.config. This way the class can be made re-usable without always naming my connectionstring in web.config to "MyConnString".
1: I DON'T want to pass connectionstring in every static method as a parameter.
2: I must be able to access the methods similar to Membership.CreateUser i.e. static.
I am looking over the web in parallel but any inputs/guidance will help.
Edited: I have updated my code sample, to clear some confusion about issues using static class. Here is a new question I posted to clarify that. Sorry about confusion.
I typically discourage sharing one SqlConnection instance across several requests. Even if you enable MARS, you can run into performance issues. I think when your connection receives a non-read command, the connection buffer will pause all current reads until the write finishes. The only thing you're really saving is the time it takes to establish a connection.
SqlConnections are pooled so you can configure the provider to have a min / max number of instances available to soliciting clients. Keep in mind this is also controlled by whatever database you're connecting to; assuming you're connecting to a SQL Server instance, SQL Server has its own maximum connections allowed setting.
Instead of allowing clients to determine when to open/close a shared SqlConnection instance, I suggest having your public members take in either a command string or command parameters. Then, similar to what your sample has suggested, open a connection from the pool and execute the command.
The sample code above is just that - a sample of a concept I use at work. The sample does now have maximized error handling but is very flexible in how results are returned and handled. The
SqlResults
class simply contains aSqlDataReader
property and can be expanded to include errors.As far as making any of this
static
, it should be fine as long as you enable a way to make a singleton instance of the provider class and continue to not have any mutable properties be shared (potentially across various requests/threads). You may want to consider some sort of IoC or Dependency Injection approach for providing the connection string given your request.EDIT
Yield allows the caller to use the returned object before the execution context returns to the method yielding the return for continued execution. So in the sample above, a caller can do something like this:
without the connection closing while we handle the results. If you notice in the sample, we have
using
statements for ourSqlClient
objects. This approach allows result set handling to be decoupled fromMySqlHelper
as the provider class will take care of the would-be-duplicate SQL provision code, delegate result handling to the caller, then continue with what it has to do (i.e. close the connection).As for IoC/DI, I personally use Castle Windsor. You can inject dependency objects as properties or construction parameters. Registering an Inversion of Control container as your dependency resource manager will allow you to (among other things) return the same object when a type of resource is requested. Basically, for every caller class that needs to use
MySqlHelper
, you can inject the same instance when the caller class is instantiated or when the caller class references its publicMySqlHelper
property. I, personally, prefer constructor injection whenever possible. Also, when I say inject, I mean you don't have to worry about setting the property value as your IoC/DI does it for you (if configured properly). See here for a more in depth explanation.As another note, the IoC/DI approach would really only come into play if your class is non-static such that each application can have its own singleton instance. If
MySqlHelper
is static, then you could only support one connection string unless you pass it in, which in your original question, you'd prefer not to do so. IoC/DI will allow you to use yourMySqlHelper
property member as if it were static though since the registered container would ensure that the property has a proper instance.Here is the complete code of a
SqlHelper
that I'd used on some small projects. But carefull withstatic
for this kind of class. If you will use it for Web project, remember that the connection will be shared at the same instance for all users, which can cause bad problems...Sample usage:
But if you really want
static
(if you is on a single user enviroment), just putstatic
on all methods.the only thing i can think of that meets the qualifications you laid out is to use dependency injection, a static constructor, and inject in an something like an
IConnectionStringProvider
. this seems like about the most convoluted thing i can think of, so you might like it. :)edit
after reading your comment, it seems like you just want to be able to reference any connection string, but only one connection string per application. i'd say just add an element to
appSettings
namedMySqlProviderConnection
with the value being the name of the connection string you want to use.then in your helper, check for the existence of the appsetting, get its value, and pass it in to your
ConfigurationManager.ConnectionStrings
call. that way your provider could use any connection you want, without changing any code.