I have a class library (CoreLib) which exposes a bunch of functionality, both out-of-the box and through add-ons.
The interface for interacting with addons is very general (on purpose), where each addon can return metadata describing the properties it exposes. The base class for addons looks something like this:
public abstract class AddOnBase
{
public abstract IList<PropertyDescriptor> GetPropertyDescriptors();
public void SetPropertyValue(Guid propertyId, object value);
public object GetPropertyValue(Guid propertyId);
}
This generality works very nicely for someone building a UI to expose the addon's properties.
However, if someone wants to work with the addon in plain old .NET code, it's way too cumbersome. For example:
// Declare some published IDs to identify the "Recipe" addon and its properties.
Guid recipeAddOnId = new Guid("...");
Guid recipeTitlePropId = new Guid("...");
Guid recipeCategoryPropId = new Guid("...");
AddOn addon = coreLib.GetService(IAddOnService).GetAddOnInstance(recipeAddOnId);
// Set some properties in the recipe addon.
addon.SetPropertyValue(recipeTitlePropId, "Cupcakes");
addon.SetPropertyValue(recipeCategoryPropId, "Baked Goods");
// Do something with the addon.
coreLib.GetService(IAddOnService).ProcessAddOn(addon);
This works fine, but there's all these GUIDs that the developer needs to look up, and it makes everything really clunky.
I would much rather the developer could add a reference to the RecipeAddOn and write something like this instead:
Guid recipeAddOnId = RecipeAddOn.Id;
AddOn addon = coreLib.GetService(IAddOnService).GetAddOnInstance(recipeAddOnId);
// Cast the instance returned by CoreLib to a RecipeAddOn
RecipeAddOn recipe = (RecipeAddOn)addon;
// Set some properties in the recipe addon.
recipe.Title = "Cupcakes";
recipe.Category = "Baked Goods";
// Do something with the addon.
coreLib.GetService(IAddOnService).ProcessAddOn(recipe);
Here, not only do they not have to mess with GUIDs to identify properties, but they get to work with more concrete classes and get intellisense to help them in their development.
My current solution is to have the developer reference both CoreLib and RecipeAddOn, with CopyLocal
set to false
on the latter. However, it's been suggested that this can lead to DLL hell (see Why do I need an AssemblyResolve handler for an assembly which is already loaded?), so I wanted to ask what is the proper way to do this.
See Question&Answers more detail:
os