views:

421

answers:

2

I'm currently designing solution where the domain model & the repository can be extended by application plugins. Now, i have come across a few issues that i am listing below.

  1. My first issue is making domain model extensible. I was thinking about using inheritance here, but honestly, i have no idea how i can leverage multiple plugin assemblies extending the same domain object. I'm kind of leaning toward making every domain object partial and allowing plugins extend it this way. In case i have multiple plugins extending the same domain object, i won't have to worry about loading different extended domain assemblies for each plugin. I would still have only one merged domain object at run-time. Any ideas on this?

  2. Another issue is extending the NHibernate mapping file. I could have each assembly embed mapping file for the domain object it's extending and have my NHibernate manager load it instead of the one provided in the core domain. Once again, the issue is what if i have multiple plugins extending the same domain object. I could have one plugin overriding mapping file for the other. The solution i have to the last problem is not so great, but I was thinking about including a checksum into the plugin assembly as a signature for the original mapping file it used before extending it. I can verify this checksum during load and only load the plugin map if the checksums match. Pretty ugly, but at least i won't be overriding any maps that differ from the base map used to extend upon in the plugin assembly.

Any way, i'd like to hear what you guys think about this. Thanks!

+1  A: 

Hi,

The good news is that what you are asking for is possible and not that difficult to manage.

About plugin management, you can take a look at Microsoft Prism (http://msdn.microsoft.com/fr-fr/magazine/cc785479.aspx) which as several nice features about modular application development.

About 1. You can map subclasses in separate mappings, in separate assemblies, look for NH documentation. A separate mapping file for a subclass looks like this :

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
  <subclass name="YourClassFullName, YourPluginAssemblyName"
            extends="YourParentClassFullName, TheAssemblyWhereYourBaseClassIsDefined"
            discriminator-value="whateveryouwant">
    ... add your subclass mapping here ...
  </subclass>
</hibernate-mapping>

About 2. You can keep your core domain mapping. A simpler way would be to create a service (let's say IMappingLoader) your plugins can use to register your extra mappings (without overriding the base class mapping). Your implementation of this service would add your mapping to NH Configuration class. For example, in Microsoft Prism, all your plugins must implement the IModule interface, which function Initialize() is called when it is loaded. This function is the ideal place to call your IMappingLoader service.

Hope it helped.

Nelson
Thanks a bunch! I remember briefly reading about the subclass attribute, but i never gave it much thought. The ability to do this in NH definitely makes things much easier than i thought.
Sergey
+1  A: 

To get domain model extensible I'll use lots of factories. Factories can be swap in/out via dependency injection and domain objects should be coded against interfaces.

Mapping could be done for instance via Fluent NHibernate and these could be in that plugin assembly.

Finally I would add loadable configuration to that plugin assembly, which setups DI container and load new mappings. For main assembly there could be scanner for plugin configurations. Maybe MEF could be helpful here or you could make your own, which should not be complicated.

Marek Tihkan