1

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.

Sinatr
  • 20,892
  • 15
  • 90
  • 319

1 Answers1

1

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>())
Community
  • 1
  • 1
Tim S.
  • 55,448
  • 7
  • 96
  • 122
  • Thanks for answer. I've those 2 in mind =P. Problem with generics is that there is no `new(someParameter)` constraint and you construct instance every call (I am not sure if it's harmless, as it's auto-generated class), but return another instance made with reflection. So first one is probably the best. When asking, I was hoping for some *unnatural* answer (or interesting one, with the use of delegates to example). – Sinatr Dec 05 '14 at 09:10
  • Regarding constraint of constructor with parameter, it could be singleton (to only obtain name and be able to call non-static methods) which contains method with delegate as parameter, like [here](http://stackoverflow.com/a/1852854/1997232). Point is, there are more methods to be *moved into base class* if possible and I need to find the right approach. – Sinatr Dec 05 '14 at 09:52