【问题标题】:Using MEF , what would be the Extensible points in a web application?使用 MEF ,Web 应用程序中的可扩展点是什么?
【发布时间】:2014-07-06 10:41:18
【问题描述】:

因此,我决定在我的新 ASP.NET MVC Web 项目中使用 Microsoft 可扩展性框架 (MEF)。该项目是一个非常典型的员工管理系统,具有 3 个传统层:- 表示层(带有视图和控制器)、业务层(带有业务对象),当然还有数据访问层。经过一番研究,我读了很多,MEF应该帮助我们实现插件架构。这就是我似乎卡住的地方。我无法与这个可插拔部分联系起来。我很确定,因为 MEF 是核心 .NET 框架的一部分,它不限于任何特定类型的应用程序,并且应该是一般有用的。我只需要从新的角度看待我的应用程序结构,这就是我需要一些有用的见解的地方。

由于我仍在尝试开始使用 MEF,我的主要问题是;我的应用程序中的主要可扩展(可插入)点是什么?使用 MEF 的 compose 方法通常应该组合哪些对象,使用 MEF 而不是传统方式这样做有什么优势?

【问题讨论】:

  • 这听起来像是在寻找问题的解决方案......
  • 如果您不尝试使用 MEF 解决特定问题,那么您为什么要尝试使用它?你买了一把闪亮的新锤子,正在乡下寻找钉子?
  • 1) 现在,我只想了解 MEF 背后的概念,以便以后使用它。 2) 这样我就可以为战争做好准备,我实际上将不得不使用我闪亮的新锤子。
  • @MrClan 对我的回答有何评论?它有帮助还是不是您所期望的?

标签: asp.net-mvc design-patterns mef


【解决方案1】:

在您在问题中描述的情况下,MEF 不会帮助您解决可扩展性问题,因为它似乎没有任何问题。对于这种特殊情况,MEF 可以带来的是依赖注入。如果您以一种表示层依赖于业务抽象而业务层依赖于数据访问抽象而不是具体实现的方式来开发您的应用程序,您将获得一个高度解耦的应用程序,该应用程序易于测试、维护和更改而不会影响不必要的组件。这是执行此操作的一种方法:

假设您有对员工执行 CRUD 操作的数据访问类:

[Export(typeof(IEmployeeRepository))]
public class EmployeeRepository : IEmployeeRepository
{
    //Some logic here
}

如您所见,EmployeeRepository 类实现了IEmployeeRepository 接口,该接口增加了开发解耦应用程序所需的抽象级别。现在假设在业务层中有一个类需要从EmployeeRepository 类中调用一些方法。为了能够调用EmployeeRepository 的方法,您需要它的一个实例。不使用 MEF(或任何其他 IoC 框架,这将是一种方法:

public class EmployeeManager
{
    private EmployeeRepository _employeeRepository;

    public EmployeeManager
    {
        _employeeRepository = new EmployeeRepository();
    } 
}

通过使用上面的代码示例,在EmployeeManagerEmployeeRepository 类之间创建了硬依赖关系。这种硬依赖在编写单元测试时很难隔离,并导致EmployeeRepository 类的任何更改都会直接影响EmployeeManager 类。通过稍微重构代码示例并将 MEF 放入游戏中,您将得到:

[Export(typeof(IEmployeeManager))]
public class EmployeeManager : IEmployeeManager
{
    private IEmployeeRepository _employeeRepository;

    [ImportingConstructor]
    public EmployeeManager(IEmployeeRepository employeeRepository)
    {
        _employeeRepository = employeeRepository;
    } 
}

如您所见,EmployeeManager 类现在不依赖于EmployeeRepository 类,但它依赖于IEmployeeRepository 接口,换句话说,它依赖于抽象。而且它不会自己创建EmployeeRepository 类的实例。该工作留给 MEF。现在应该清楚 export 和 ImportingConstructor 属性是 MEF 的一部分,并被它用于在运行时发现部件和解决依赖关系。使用最后一个代码示例,类被解耦,易于测试和维护,您可以更改EmployeeRepository 类中的内部逻辑,而无需让EmployeeManager 类意识到它。当然,他们之间的合同,IEmployeeRepository 必须保持。

上面说的,也可以用来解耦表现层和业务层。上面也说过,可以通过使用任何其他 IoC 框架来实现,如 Ninject、Autofac、StructureMap 等。这些 IoC 框架和 MEF 之间的区别在于,如果您使用它们,您需要在应用程序启动时配置哪个实例获取遇到某些接口时创建:

//something like this, in the case of Ninject
this.Bind<IEmployeeRepository>().To<EmployeeRepository>();

另一方面,MEF 能够在运行时发现部件。在应用程序启动时,您只需要告知它在哪里寻找部件:目录、程序集、类型等。MEF 的自动连接功能(在运行时发现部件的能力)使其不仅仅是一个常规的 IoC 框架.这种能力使 MEF 非常适合开发可插入和可扩展的应用程序,因为您将能够在应用程序运行时添加插件。 MEF 能够加载它们并让应用程序使用它们。

【讨论】:

  • 好吧,不是真的阻塞...如果您检查答案中的灰色元素(包含在 `(反引号)中的元素),您会看到它们是 标签。 MEF、依赖注入、IoC、Export、Ninject、Autofac、StructureMap、Directory、Assembly 和 Type 不是代码
  • 你是对的。我一直在使用反引号来突出显示,但它应该用于内联代码。
  • 是的。如果您绝对必须突出显示某些内容。使用 粗体 :)
  • @IlijaDimov 感谢您的回复。您能否提供一些在任何应用程序中可扩展点的实际示例?
  • @MrClan Checkout nopcommerce 架构 (nopcommerce.codeplex.com)。它是可插拔的电子商务系统。您应该了解实现可插拔架构意味着什么。如何使用 MEF 和 ASP.NET MVC 实现可插拔架构?看看下面的链接:stackoverflow.com/questions/21017036/….
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-11
  • 2013-07-07
  • 2016-01-29
  • 1970-01-01
  • 2016-11-01
  • 1970-01-01
  • 2012-07-30
相关资源
最近更新 更多