-1

So I'm writing a framework for my projects.

This framework should take the PT out of starting new projects by providing a generic foundation upon which the project is built.

The framework includes:

  • A generic db context to which is provided by the application a database name
  • Generic data models that include "common" data such as a user model with an email address and password property
  • Generic CRUD functionality for the generic data models

So far I feel like I've got stuck early on in my attempt to make my DbContext class as generic as possible. See below:

public class DataEntities : DbContext
{
    public string _databaseName { get; set; }
    public string DatabaseName
    { 
        get
        {
            if (String.Compare(_databaseName, String.Empty, StringComparison.InvariantCultureIgnoreCase) == 0)
            {
                return "LYSDatabase";
            }
            else
            {
                return _databaseName;
            }
        }
        set;
    }
    public Initializer _initializer { get; set; }

    public enum Initializer
    {
        DropCreateDatabaseAlways = 1,
        DropCreateDatabaseIfModelChanges = 2,
        CreateDatabaseIfNotExists = 3
    }

    public DataEntities()
        : base(DatabaseName)
    {
        var Init;
        switch (_initializer)
        {
            case Initializer.CreateDatabaseIfNotExists:
                Init = new CreateDatabaseIfNotExists<DataEntities>();
                break;
            case Initializer.DropCreateDatabaseAlways:
                Init = new DropCreateDatabaseAlways<DataEntities>();
                break;
            case Initializer.DropCreateDatabaseIfModelChanges:
                Init = new DropCreateDatabaseIfModelChanges<DataEntities>();
                break;
        }

        Database.SetInitializer<DataEntities>(Init);
    }
}

I have 2 errors in this code and I've been unable to find a solution to either of them:

On the line : base(DatabaseName):

An object reference is required for the non-static field, method, or property 'LYSFramework.DataEntities.DatabaseName.get'

As neither the class nor the constructor are static, I don't understand what it is that I've done wrong here.

On the line var Init;

Implicitly-typed local variables must be initialized

It is implicitly typed because I don't know what type to set it to yet. It should get its type later in the switch.

My questions are as follows:

  1. How do I use the string property's value in the base inheritance on the constructor?
  2. What type should I set Init to before I use it? (Ideally it should basically just be null I guess).

Thanks in advance!

Ortund
  • 8,095
  • 18
  • 71
  • 139
  • Extract `"LYSDatabase"` into a `const` and use it when calling `: base(DATABASE_NAME); – haim770 Apr 14 '15 at 17:33
  • `var Init;` you need to initialize it to a value what is it `boolean, string, integer, etc...` this is very obvious what the error is telling you btw – MethodMan Apr 14 '15 at 17:34
  • @MethodMan yes it is, but as I'm deterministically setting it's type based on what value was selected from the enum, that's where the confusion comes from – Ortund Apr 14 '15 at 17:38
  • 1
    This is simply not how the `var` keyword works. It doesn't mean "this variable can be of multiple types". See perhaps [What does “var” mean in C#?](http://stackoverflow.com/questions/4307467/what-does-var-mean-in-c) – eldarerathis Apr 14 '15 at 17:45
  • Yes I know that. How can I get it to work that the variable *can* be multiple types? – Ortund Apr 14 '15 at 18:01
  • You need to define an interface that each of your "multiple types" implements. Then declare your `Init` variable as that interface type. – BJ Myers Apr 14 '15 at 18:27

1 Answers1

2

How do I use the string property's value in the base inheritance on the constructor?

When the DataEntities constructor is called, the first thing it tries to do is call the DbContext (base class) constructor. At this point, you don't have a complete instance of the DataEntities class, so you can't pass the instance property DatabaseName into the base constructor. You'll probably need to modify the DataEntities constructor to take the database as a parameter so that you can pass it on to the base class constructor.

What type should I set Init to before I use it?

Once Init is declared, its type cannot be changed. var can only be used to declare a variable if it is initialized immediately so that the compiler can tell what type it is.

You hae to declare Init with a type that is compatible with anything you want to assign it later. You could do this a few ways:

  • [Recommended] Create an interface IDatabaseInitializer that each of your types implements, and then change your declaration to IDatabaseInitializer Init;

  • Declare Init as an object, since every class in C# implicitly inherits from object.

  • Use the dynamic keyword (not recommended - this leads to very fragile code).

BJ Myers
  • 6,617
  • 6
  • 34
  • 50
  • 1
    No need to create a new interface, all 3 types already implement [`IDatabaseInitializer`](https://msdn.microsoft.com/en-us/library/gg696323(v=vs.113).aspx) (those 3 types in his switch are part of EF, not made by the OP) – Scott Chamberlain Apr 14 '15 at 19:22
  • Well... That didn't make sense the first time I read it but that might have been because I was on the phone. Works now so thanks :) – Ortund Apr 14 '15 at 19:57