Using inherited members from base class (moving repeatable code into base class)

71 views Asked by At

I often use

using (var context = new SomeDataContext(SomeDataContext.ConnectionString))
{
   ...
}

where

abstract class DataContextBase: DataContext { ... }

partial class SomeDataContext: DataContextBase
{
    public const string DatabaseFile = "blablabla.mdf";
    public static readonly string ConnectionString = string.Format(@"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename={0};Integrated Security=True", DatabaseFile);
}

Question: Is it possible to hide creation of SomeDataContext instance and ConnectionString deep into DataContextBase?

I want to define only file name in inherited classes

partial class SomeDataContext: DataContextBase
{
    public const string DatabaseFile = "blablabla.mdf";
}

and to be able to create instances like this

var context = SomeDataContext.PropertyInBaseClassWhichCreatesInstanceOfInheritedClass;

P.S.: I add at first of how I tried to overcome the problem (without success tbh), but then I deleted it (I was making this post over hour!), because it makes question too noisy. It may looks easy at first, until you (or is it only me?) try to solve it. I tagged it dbml because of specific to DataContext things: you can't use singleton, etc.

1

There are 1 answers

2
Tim S. On

Unfortunately, there isn't some sort of virtual static, and if you call SomeDataContext.StaticPropertyInBaseClass, it compiles to the same as DataContextBase.StaticPropertyInBaseClass. I think the best you can do is something like this:

// upside: simple SomeDataContext.Instance for external users
// downside: more code in SomeDataContext
partial class SomeDataContext : DataContextBase
{
    private const string DatabaseFile = "blablabla.mdf";
    public static SomeDataContext Instance
    {
        get
        {
            return new SomeDataContext(GetConnectionString(DatabaseFile));
        }
    }
}
abstract class DataContextBase
{
    protected static string GetConnectionString(string databaseFile)
    {
        return string.Format(@"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename={0};Integrated Security=True", databaseFile);
    }
}
// e.g. using (var context = SomeDataContext.Instance)

Or

// upside: just one line in child class
// downside: a little harder for external callers, with a little less type safety
// downside: as written, requires child class to have parameterless constructor
partial class SomeDataContext : DataContextBase
{
    protected override string DatabaseFileInternal { get { return "blablabla.mdf"; } }
}
abstract class DataContextBase
{
    protected abstract string DatabaseFileInternal { get; }
    private string ConnectionString
    {
        get
        {
            return string.Format(@"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename={0};Integrated Security=True", DatabaseFileInternal);
        }
    }
    public static T GetInstance<T>() where T : DataContextBase, new()
    {
        using (var tInst = new T())
            return (T)Activator.CreateInstance(typeof(T), tInst.ConnectionString);
    }
}
// e.g. using (var context = DataContextBase.GetInstance<SomeDataContext>())