Creating a dynamic class
we have a data layer that contains classes generated by the output (tables / views / procs / functions) from the database. The tables in the database are normalized and designed similarly to the OOP project (the table for "invoice" has a 1: 1 relationship to the table for "document", the table for "invoice" has a 1: 1 relationship to the table for "item document" "etc." All access to / from databases - stored procedures (for simple tables too).
A typical class looks like (shortly):
public class DocumentItem {
public Guid? ItemID { get; set; }
public Guid? IDDocument { get; set; }
public DateTime? LastChange { get; set; }
}
public class InvoiceItem : DocumentItem {
public Guid? IDProduct { get; set; }
public decimal? Price { get; set; }
}
The problem is that database tables have relationships similar to multiple inheritance in OOP. We are now creating a new class for each database output. But each database output is a combination of "blank" tables in the database.
The ideal solution would be to have transform classes (IMHO) for the interface, use multiple interface implementations and then automatically execute the elements (these "table classes" only have properties, and the body of the properties is always the same).
For example: public interface IItem {Guid? ItemID {get; set; } DateTime? LastChange {get; set; }}
public interface IDocumentItem : IItem {
Guid? IDDocument { get; set; }
}
public interface IItemWithProduct : IItem {
Guid? IDProduct { get; set; }
}
public interface IItemWithRank : IItem {
string Rank { get; set; }
}
public interface IItemWithPrice : IItem {
decimal? Price { get; set; }
}
// example of "final" item interface
public interface IStorageItem : IDocumentItem, IItemWithProduct, IItemWithRank { }
// example of "final" item interface
public interface IInvoiceItem : IDocumentItem, IItemWithProduct, IItemWithPrice { }
// the result should be a object of class which implements "IInvoiceItem"
object myInvoiceItem = SomeMagicClass.CreateClassFromInterface( typeof( IInvoiceItem ) );
The database contains table signatures and the entire solution consists of dynamically loadable modules (over 100 modules).
What do you think is the best way to deal with it?
EDIT:
Using partial classes is good advice, the bud in our solution cannot be used because "IDocumentItem" and "IItemWithPrice" (for example) are in different assemblies.
Now if we make changes to the "DocumentItem" table, we have to go and re-generate the source in all dependent assemblies. There is almost no reuse (because multiple inheritance cannot be used). Its quite time consuming if there are dozens of dependent assemblies.
a source to share
So, you are really looking for some kind of mixed technology. Of course I have to ask why you are not using LINQ for Entity Framework or NHibernate. O / RMs handle these issues by mapping the relational model to useful data structures that have APIs to support all the transactions you need to manipulate the data in the database. But I'm distracted.
If you're really looking for mixing technology for generating dynamic code, check out Cecil in the Mono Project . This is a better way to start than trying to use Reflection.Emit to create dynamic classes. There are other dynamic code generators out there, but you can start with Cecil as the documentation is pretty good.
a source to share
If you want to continue auto-generating from the database and want to model multiple inheritance then I think you have the right idea: Change the tool to spit out multiple inheritance interfaces as well as X num implementations.
You have indicated elsewhere that the inheritance versus aggregation convention is respected and (as I understand it) you know exactly what the resulting interfaces and classes should look like. I understand that business rules are implemented elsewhere (perhaps in the business rules engine?), So there is no need to modify dependent code to restore classes unless you want to use those changes or existing properties have been changed or removed.
But you are not finished. Your classes will still have the ID of the related objects. If you want to simplify your client code, you must have references to related objects (without worrying about the corresponding object id), for example:
public class Person{
public Guid? PersonID { get; set; }
public Person Parent { get; set; }
}
This will simplify the work with the client. When you think about it, going from IDs to links is a job you should be doing anyway; it is better to do it once at an average level than to let the client do it N times. Plus it makes your code less database dependent.
So, first of all, I recommend writing an OO wrapper for the auto-generated classes. You would program pretty much anything against this OO shell; just let the data access layer interact with the automatically generated classes. Surely you cannot reuse inheritance metadata in a database (defined through conventions, I assume?), But at least you won't carve out a new path.
As opposed to what you now look like an anemic data model or worse.
a source to share
The script is incomprehensible to me.
If the code is generated, you don't need the magic: add some metadata to database objects (such as advanced properties in SQL Server) that denote "base" interfaces and modify your template / tool to consider flags.
If the question is about multiple inheritance, you're out of luck with .Net.
If the code is generated, you can also use partial classes and methods (are you using .Net 3.5?) To generate the code in different source files.
If you need to generate code at runtime, there are many methods, not least ORM tools.
Now can you be more outspoken in terms of design?
a source to share