1

I'm building the app which will work with SQLite and what I want to do now is to get table creation strings for each entity which should be stored with code like this:

table_creation_string1 = Book.GetTableCreationString();
table_creation_string2 = Scroll.GetTableCreationString();

Which will allow me to do the minimal work with new entities creation using custom attributes to store table name and fields names.

Here is my setup example:

[System.AttributeUsage(System.AttributeTargets.Class)]
public class DBItemAttribute : System.Attribute
{
    public string TableName;
    public DBItemAttribute(string table_name)
    {
        TableName = table_name;
    }
}

internal abstract class DBItem
{
    ...
}


[DBItemAttribute("book_table")]
internal class Book : DBItem
{
    ...
}

[DBItemAttribute("scroll_table")]
internal class Scroll : DBItem
{
    ...
}

The problem I faced is that I can't get an attribute value for Book and Scroll classes without constructing the object. In other terms - using smth like that:

string table1 = Scroll.GetTableName();
string table2 = Book.GetTableName();

with next values output

"scroll_table"
"book_table"

So I'm looking for the best solutions for that or some good alternatives.

I've already learned that static method in base class will not work for that due it seems to be not possible to get derived class info calling static method defined in base.

UPD: The code like

table_creation_string1 = new Book().GetTableCreationString();

works for a sure, but I wonder if it can be done in way I've described above.

  • You should be able to get attribute information without constructing objects. Attributes are a property of type. Check this out: https://stackoverflow.com/questions/2656189/how-do-i-read-an-attribute-on-a-class-at-runtime – peeyush singh Apr 22 '19 at 05:47
  • Also why do you want to reinvent the wheel, assuming there would already be libraries dealing with DB creation/handling already: https://learn.microsoft.com/en-us/ef/ef6/modeling/code-first/workflows/new-database – peeyush singh Apr 22 '19 at 05:49
  • You're right, I can get t without constructing the object, but in this case I need to write the actually same method in each of classes I use and there are dozens of them. Thanks for the link, I'll check it shortly – Слава Картушин Apr 22 '19 at 05:54

3 Answers3

2

Attributes is a properties of a class, so you don't need to create an instance of this class to get those values. You can create a separate helper-class for this:

internal static class DBHelpers
{
    public static string GetTableName<TDBItem>()
        where TDBItem : DBItem
    {
        var attribute = typeof(TDBItem).GetCustomAttribute<DBItemAttribute>();
        return attribute?.TableName;
    }
}

So now you can use it like this:

var tableName1 = DBHelpers.GetTableName<DBHelpers>();
var tableName2 = DBHelpers.GetTableName<Book>();
vasily.sib
  • 3,871
  • 2
  • 23
  • 26
1

Static class method

Just change internal class Book and internal class Scroll to static, as static class Book and static class Book. This is the whole purpose who the static classes.

Static Class Definition

A static class is a class that can't be instantiated. The sole purpose of the class is to provide blueprints of its inherited classes. A static class is created using the "static" keyword in C#. A static class can contain static members only. You can‘t create an object for the static class.

Instantiate and call the method Otherwise you can instantiate it and call the method like this: new Book().GetTableName()

Jonathan Gagne
  • 4,241
  • 5
  • 18
  • 30
  • The thing is that I need to operate with the objects all the time and this case is the only case where I want to use them without creating object. The main idea was to create classes that can be used to load the information from database about entities but at the same time I want to use them like a "template" for table creation – Слава Картушин Apr 22 '19 at 05:43
  • oh I see and what about `new Book().GetTableName()` then ? I will add it as alternative into my solution – Jonathan Gagne Apr 22 '19 at 05:45
  • That works for a sure, just wonder if there is a way to do that like I described in post, some kind of syntactic sugar for me – Слава Картушин Apr 22 '19 at 05:48
  • The whole thing about attributes is that you should **not** create an instance of class to get this value. If it's work for you - just remove all this attributes-stuff and create normal internal property. – vasily.sib Apr 22 '19 at 05:50
  • 1
    @vasily.sib used attributes to store the field names for DB initially which can be different from the field name in the class. So I can get UPDATE, INSERT and other strings for any of these objects and change the value names easier – Слава Картушин Apr 22 '19 at 05:58
0

try this, Add a class name and its correspondent table name, when you create new.


    public class ClassFactory
        {
            public static Action GetTableName(string className)
            {
                switch (className)
                {
                    case "Scroll": return "Book_table";
                    case "Book": return "Book_table";
                }
            }
         }

call this class :


string table1 = ClassFactory.GetTableName("Scroll");
string table2 = ClassFactory.GetTableName("Book");

Abhay Agarwal
  • 93
  • 1
  • 9