Even with your idea of having an abstract ContentBase class, you won't be able to access a custom behavior for each derived class; here is a small test i tried to see if your idea could be used:
public abstract class ContentBase<T>
{
public static Func<string> TypeLocator { get; set; }
static ContentBase()
{
TypeLocator = () => typeof(T).Name;
}
}
public class Content1 : ContentBase<Content1> {
private static string Content1Type = "The type of Content 1";
static Content1()
{
TypeLocator = () => Content1Type;
}
}
public class Content2 : ContentBase<Content2> {}
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Content1.Type => " + GetObject<Content1>()); // Content1
Console.WriteLine("Content2.Type => " + GetObject<Content2>()); // Content2
}
private static string GetObject<TContent>() where TContent: ContentBase<TContent>
{
var typeLocator = typeof(ContentBase<TContent>).GetProperties()[0].GetValue(null, null) as Func<string>;
return typeLocator.Invoke();
}
}
The best you can get is the type of the TContent, which may be enough for you to explore the mapping proposition below.
I don't really see a way to implement abstract static members, but you could resort to an external registering dictionary living as a singleton throughout your program which would be used as the mapper between your Type
and your Type.DBType
public TContent Create<TContent>(string name, ...)
{
...
// SP executes a few insers and returns newly created data instance
return db.Single<TContent>(
new Sql.Builder.Append(";exec dbo.CreateContent @Type, @Name, ...", new {
Type = RegisteredTypes[typeof TContent],
Name = name,
...
}));
}