microsoft / sqlmanagementobjects

Sql Management Objects, an API for scripting and managing SQL Server and Azure SQL Database
Other
132 stars 22 forks source link

Rewrite SMO collections using generics #130

Open shueybubbles opened 1 year ago

shueybubbles commented 1 year ago

Our collection classes are based on .Net 2.0 technology and are very out of date. We should replace as much functionality as possible with reflection-free code and implement standard generic collection interfaces like IList<T> instead of requiring apps to cast.

shueybubbles commented 1 year ago

bonus points for writing a C# source generator to create the collections instead of our custom templates.

Matteo-T commented 1 year ago

bonus points for writing a C# source generator to create the collections instead of our custom templates.

I've always wanted to do that. You are bad influence!!!

aguzev commented 1 year ago

Training a neural net is trendy this year.

shueybubbles commented 1 year ago

Notes on current research:

public interface ISmoObjectFactory<T> where T:SqlSmoObject
{
  T NewObject(ObjectKeyBase key, SqlSmoState state);
}

public class TableCollection : SchemaCollectionBase<Table, Database>
{
...
  public Table NewObject(ObjectKeyBase key, SqlSmoState state) => new Table(this, key, state);
...
}
shueybubbles commented 1 year ago

Here's a potential new implementation of AlertCategoryCollection if we genericize the base classes:

using Microsoft.SqlServer.Management.Sdk.Sfc;

namespace Microsoft.SqlServer.Management.Smo.Agent
{

    ///<summary>
    /// A collection of AlertCategory objects associated with a JobServer
    ///</summary>
    public sealed class AlertCategoryCollection : SimpleObjectCollectionBase<AlertCategory, JobServer>
    {
        /// <summary>
        /// Constructor needed for use by reflection.
        /// </summary>
        /// <param name="parentInstance"></param>
        internal AlertCategoryCollection(SqlSmoObject parentInstance) : base((JobServer)parentInstance)
        {
        }

        protected override string UrnSuffix => AlertCategory.UrnSuffix;

        internal override AlertCategory GetCollectionElementInstance(ObjectKeyBase key, SqlSmoState state) => new AlertCategory(this, key, state);

    }
}

We can remove the need for collection codegen because Visual Studio will essentially write the code for you once you declare the base class.

shueybubbles commented 1 year ago

...only 127 more collections to update

shueybubbles commented 1 year ago

BTW I am delaying IList<T> simply because there are some requirements about forcing initialization of the collection before enumeration that are not obvious how to reconcile with this interface just yet.