Thanks for the input. One of the reasons for integrating the tables with the existing ones is that EF 4.1 (Entity Framekwork), will automatically create the foreign key relationships between you tables and the existing ones. Although you can go create an address entry and have your entity point to it, there is no database 'knowledge' of this. Generally in databases, you want to give the database as much knowledge of the relationships of entities so it can ensure data entegrity (this is why I'm going on with integrating it all together).
This is what've been able to do so far without touching a single line of nopCommerce base code:
1) I've add 5 new tables for licensing, three with direct relationships with existing tables (Affiliate, Product, and Customer)
2) I've done this by adding a new 'Extentions' directory to both the Nop.Core (Domains directory) and Nop.Data(Mapping directory).
3) Under both of those directories, I've created a 'Licensing' directory (this allows other extentions to co-exist as different directory names under the 'Extentions' directories.
4) I've added my new domain classes to the Nop.Core.Domain.Extentions.Licensing directory using that same name space (e.g. License). I've create these in the same manner as other Domain classes in nopCommerce (ie same base classes, using's etc)
5) I've added partial class for existing entities (domain entries) that I want to modify. Because the nopCommerce class all already 'partial' there is no problem of adding more to the class by creating your own partial version to it. So for example, I need to have a Licenses collection in the existing Customer entity, so I created my own Customer.cs in the Nop.Core.Domains.Extentions.Licensing directory:
namespace Nop.Core.Domain.Customers
{
/// <summary>
/// Represents a customer
/// </summary>
public partial class Customer : BaseEntity
{
ICollection<License> _licenses;
public virtual ICollection<License> Licenses
{
get { return _licenses ?? (_licenses = new List<License>()); }
set { _licenses = value; }
}
}
}
The net effect of these 2 partial classes (both the nopCommerce verson and mine) is a merge of the two done at compile time (note these 2 partials have to be in the same assembly)
6) In the above examples (and it turns out to be true for my other partial classes), all I needed was to add a 'Navigation' property to the entity (which doesn't modify the sql database tables).
7) In the Nop.Data (Mapping.Extentions.Licensing directory), I added the "Mapping' classes for my new domain entities e.g. LicenseMap.cs. The entry that establishes the ForeignKey relations ship to Customer looks like this:
// Customer foreign key
this.HasOptional(L => L.Customer) // unsold license don't yet have a relationship with a customer so this is optional
.WithMany(C => C.Licenses) // this refers back to the Licenses property in my new partial Customer.cs class
.HasForeignKey(L => L.CustomerId); // this refers to the int field I have in my license.cs class that has the ID for the Customer
8) As long as the relationship of an existing entity is one to zero or one or many to a new entity (ie a customer can have many licenses), then I don't believe that you need to modify the mapping class for the existing entity. With the partial class, you can even add a new field (but this will change the database structure). The only issue (that I'm not running into because I don't need it) is that if you have a situation where an existing entity has a relationship which in it's self is a many. Then you would need to modify the existing tables 'mapping' class.
One of my goals in making these changes is to make then in such a way as to minimize any conflicts with new versions of nopCommerce (obviously, the more tables I need to interact with the higher probability of potential conflict, but I do believe that if you stick to the core common ones, then there is a lower probability). The one things that is missing for a complete solution is how to handle the situation where you need to add additional 'mappings' to an existing entity. I think that this could be done with a small change in how NopObjectContext.OnModelCreating works. What I propose is that if you have to extend the mapping of an existing entity map, that you create a subclass the original map class with some sort of naming convention (some sort of naming convention is required in order for my proposed changes to the OnModelCreating methods to work). OnMethodCreating method in (NopObjectContext) current uses reflection to find all classes that have a direct generic superclass of 'EntityTypeConfiguration<>' in the assembly that contains the map classes (Nop.Data). The change required would be to first find those classes that have 'EntityTypeConfiguration<>' as a superclass but indirectly (ie the exiting CustomerMap class derives from the EntityType.. class and then the CustomerAddMap?? class derives from the CustomerMap class). So we examine and use those first and discard the classes between it and the 'EntityType...' superclass.
--------------------------
I believe that I can then add my services, controllers etc back in my plugin (haven't done that yet).
So in conclusion, I've proposed 2 ares for extention: a new way for database changes (new tables, relationships etc) and the existing 'plugin' method for adding new processing, business rules, views etc
-----------------------------------------------------------------------------------------------
Unit testing:
So far I've used the existing tests (because as a by product they create a database with all the new tables, but right now as they are setup, they use SqlCE database which doesn't show all the foreign key relations ships.
I will be adding unit tests for my database extentions by referencing the exsing Nop.Core.Test and Nop.Data.Tests to make use of their common test base classes in a new project ( maybe 2 - one for Domains and one for mappings) and then another for my plugin.
Obviously I believe that what I've proposed here is a cleaner way to extend nopCommerce (especially in the database area)
Bernie