让人们使用我加载的AddOn中的类型的正确方法是什么 [英] What's the correct way to let people use the types in an AddOn that I've loaded

查看:126
本文介绍了让人们使用我加载的AddOn中的类型的正确方法是什么的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个类库(CoreLib),它提供了许多现成的功能和通过插件提供的功能。

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);
}

此通用性对于构建UI来公开插件属性的用户非常有用。

This generality works very nicely for someone building a UI to expose the addon's properties.

但是,如果有人想使用纯旧的.NET代码处理插件,那就太麻烦了。例如:

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);

这很好,但是开发人员需要查找所有这些GUID,并且可以完成所有工作

This works fine, but there's all these GUIDs that the developer needs to look up, and it makes everything really clunky.

我宁愿开发人员可以添加对RecipeAddOn的引用并编写如下内容:

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);

在这里,他们不仅不必弄乱GUID来识别属性,而且可以工作

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.

我当前的解决方案是让开发人员同时引用CoreLib和RecipeAddOn,并使用在后者上,CopyLocal 设置为 false 。但是,建议这样做会导致DLL崩溃(请参阅为什么对于已经加载的程序集,我需要一个AssemblyResolve处理程序?),所以我想问一问正确的方法是什么。

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.

推荐答案

我的扩展程序设置总是像这个。从C和Pascal时代开始,每个人都会发布带有接口的头文件或pascal单元以及要链接的lib / obj文件。

My extension setup is always like this. It's from days of C and Pascal where everybody publishes an header file or pascal unit with interface and a lib/obj file to link with.


  • 客户

  • InterfaceDll

  • ImplementationDll

客户参考接口dll包含 IRecipeAddon 接口。在运行时客户端上还将加载Implementation dll,创建 RecipeAddon 具体类的实例,并将其强制转换为 IRecipeAddon 接口。开发人员获得了智能感知,并且添加的实现没有与客户端代码混合在一起。

Client references Interface dll with contains IRecipeAddon interface. On Runtime client also loads Implementation dll, creates an instance of RecipeAddon concrete class and casts it to IRecipeAddon interface. Developer gets intellisense, and add on implementation does not mixed with client code.

这篇关于让人们使用我加载的AddOn中的类型的正确方法是什么的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆