There are several ways of controlling connections in SMO -- you can control pretty much any aspect of a SMO connection.
Let's take a look at a typical way how you would obtain a connection using a simple C# sample:
When you run this sample it will print the version, and edition, but you will also notice that the Connect() call is missing. Is there a need to call Connect()? The answer is both "yes", and "no". When you do not call Connect(), SMO will automatically obtain a connection from the connection pool when it needs one (in this case when accessing the svr.Information.VersionString/Edition properties), and after the operation has finished it will return that connection to the pool. This is a nice model as it stops you from needing to worry about when to call Disconnect(). SMO will do that bookkeeping for you and if your application has to exit because of a failure you do not need to release the connection -- SMO already has done that for you.
You can override that behavior by explicitly connecting:
What happens here is that SMO will obtain a connection from the connection pool on your request, and will not automatically release it to the pool, until you call Disconnect().
This is very much the same pattern that you would use in SQL-DMO. Also, if you are not able to connect to the server, you will get an exception during the Connect() call. However, there is one slight difference. The connection that is obtained comes from a connection pool. If you call Disconnect() and Connect() in succession then you will likely get the connection from the pool, so this allows you to efficiently manage your connections. Connection pooling means the connection is not immediately closed. It’s up to the connection pool to close it when the lifetime expires.
In some cases you want to not draw connections from a pool, but make sure that you get a non-pooled connection that you can hold on as long as your application is running. This can be helpful when running in single-user mode, or when you are paranoid about SMO to do the right thing with your connections and want to have complete control over the connections that are managed. This can be simply accomplished by setting the NonPooledConnection property to true.
The connection is then a dedicated connection that will not be returned to the pool. SMO will again, like with pooled connections, connect on demand, but in this case it will hold on to the connection until you specifically call Disconnect(). Connecting is in this case much more expensive, as there will not be a connection in the pool. This type of connection however guarantees that you have that connection for the lifetime of your application. For example, SQL Server Management Studio uses such a connection.
You can share connections between SMO Server instances, and pass and Create a new ServerConnection object based on an existing object, which is helpful if you need multiple connections with the same setting:
Server svr = new Server();
svr.ConnectionContext.NonPooledConnection = true; // comment this out to see what happens to the SPID'sConsole.WriteLine(svr.ConnectionContext.ProcessID);// do work...
// Pass the connection on to new Server instance -- the connection is reused
Server svr2 = new Server(svr.ConnectionContext);
// do work...
// The Copy() method will create a new object, and will use a new connection to the server
Server svr3 = new Server(svr2.ConnectionContext.Copy());
Console.WriteLine(svr3.ConnectionContext.ProcessID);// do work...
If you run this example, you will see that the ProcessID (SPID) only differs for svr3, as it will not use the existing connection.
Comment out the indicated line, and see if you understand what's happening! (please post a response, don't be shy! ;-).
There are various other settings of the ServerConnection object that can be manipulated to finetune SMO's behavior. Examples of this are MaxPoolSize, PooledConnectionLifeTime. Take a look at the object and you will find that all possible connection settings are available.