asp.net-mvc-3 - MVC 3 和 MEF 以及向主应用程序添加插件

标签 asp.net-mvc-3 entity-framework-4 mef

我是 MEF 的新手,我真的很困惑! stackoverflow 中有很多有用的文章和简洁的问题和答案。我下载了@matthew-abbott 在他的blog 中上传的示例。 ,但我不知道如何添加新的插件或扩展来扩展主 Web 应用程序,我的意思是像你看到的 here .

编辑:
我还为我的数据访问层应用程序使用 Entity Framework 、代码优先方法和工作单元,如果我的插件需要数据访问并且(我的意思是插件有自己的模型)想要使用我创建的 DAL 怎么办?如您所知,每次模型更改时,DbContext 都会抛出错误并告诉重新创建 DB,是否有任何方法或其他 ORM 可以动态地接受扩展 DAL?

最佳答案

该特定示例显示了我们如何将 MEF 与 MVC3 的新 DependencyResolver 集成。它为 MVC 架构中的各种扩展点提供了服务定位机制。我的博客上还有其他几篇文章详细介绍了有关可能的插件架构如何工作的更多信息,这些文章可在以下位置获得:

  • Modular ASP.NET MVC using the Managed Extensibility Framework (MEF), Part One
  • Modular ASP.NET MVC using the Managed Extensibility Framework (MEF), Part Two
  • Modular ASP.NET MVC using the Managed Extensibility Framework (MEF), Part Three

  • 还有很多精彩的文章,我的建议是也阅读:
  • ASP.NET MVC and the Managed Extensibility Framework (MEF)通过 Maarten Balliauw
  • Defining Web-scoped parts with MEF通过蒂姆·罗伯茨

  • MVC 是一种非常灵活的体系结构,可以通过多种方式对其进行扩展,但是由于 ASP.NET 应用程序在 IIS 中运行的性质,您需要非常仔细地考虑部件的生命周期。例如, Controller 只能用于一个请求,因此您可能需要确保您的 Controller 具有特定的 CreationPolicy . Tim Robert 关于 Web-scoped parts 的文章特别值得一读。

    希望这足以为您指明正确的方向。

    编辑:由于 MEF 提供的模块化特性,确保您的不同层解耦很重要。您已指定您使用的是 Entity Framework ,但现实情况是,EF 可能只应在您的数据层中使用。通常,MVC 架构会提升 View 模型而不是域模型。为此,使用类似于存储库模式的东西来定义可能很有用,例如这是一个模拟UserRepository :
    [Export(typeof(IUserRepository))]
    public class UserRepository : IUserRepository
    {
      public IEnumerable<UserViewModel> GetUsers() 
      {
        // Get values here from EF as domain models
        // And return them as view models?
      }
    }
    

    我们可以将其导出并注入(inject) Controller :
    [ExportController("User"), PartCreationPolicy(CreationPolicy.NonShared)]
    public class UserController : Controller
    {
      private readonly IUserRepository _repo;
    
      [ImportingConstructor]
      public UserController(IUserRepository repo)
      {
        if (repo == null)
          throw new ArgumentNullException("repo");
    
        _repo = repo;
      }
    
      public ActionResult Index()
      {
        var users = _repo.GetUsers();
        return View(users);
      }
    }
    

    这只是一个非常简单的示例,但与许多 IoC 容器一样,MEF 也支持依赖注入(inject)。只要一个部件提供了合适的导出,就可以在合成时将其导入(通过属性注入(inject)或构造函数注入(inject))到另一个部件。

    我的建议是反对将 EF 暴露给您的观点,因为这会使它们明确依赖它。通过注意解耦并只在正确的层公开正确的类型,您的架构将变得更加健壮、灵活和可测试,这使得维护和更新它变得更加容易。作为另一个简单的例子,下面是我们如何测试我们的 Controller :
    [Test]
    public void UserController_CreatesViewResult_WithListOfUsers()
    {
      var mock = new Mock<IUserRepository>();
      mock.Setup(m => m.GetUsers()).Returns(new[] { new UserViewModel { Name = "Matt" } });
    
      var controller = new UserController(mock.Object);
    
      var result = controller.Index();
    
      Assert.That(result is ViewResult);
      // Other assertions.
    }
    

    因为我没有将 EF 紧密耦合到我的 View 中,所以我的 Controller 更易于测试,我可以模拟一个合适的存储库并在我需要的地方进行测试。

    重要的是规划你的架构。

    关于asp.net-mvc-3 - MVC 3 和 MEF 以及向主应用程序添加插件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7361157/

    相关文章:

    c# - 带逗号的百分比正则表达式

    c# - ASP.NET MVC4 如何跨系统存储变量?

    c# - 无法解析符号 ObjectStateManager

    c# - MEF 2 - 未找到与具有多个重载的构造函数的约束相匹配的导出

    reflection - MEF 与反射

    javascript - 未捕获类型错误 : Object [object Object] has no method 'jqxmaskedinput'

    c# - 针对接口(interface)和 Entity Framework 4.0 进行编程

    entity-framework - 使用 Entity Framework 4 在运行时打开 SQL CE 文件

    c# - MEF - 将默认创建策略更改为 NonShared

    asp.net-mvc-3 - 使用 knockoutjs 创建链接