gpt4 book ai didi

asp.net-mvc - 我们如何使用 ASP.NET MVC 4 和 MEF 2 支持模块化和可测试模式?

转载 作者:行者123 更新时间:2023-12-01 23:30:14 28 4
gpt4 key购买 nike

我们尝试将 MEF 2 与 ASP.NET MVC 4 结合使用来支持可扩展应用程序。这个问题实际上有两个部分(希望诸神没问题):

  1. 我们如何使用 Microsoft.Composition 和 MVC 容器代码 ( MEF/MVC demo source ) 来替换 Ninject 作为 ICoreService 的 DI , ICoreRepository , IUnitOfWork ,和IDbContext
    看起来我们不能同时使用 Ninject 和 MVC 容器(我确信很多人都在说“废话”),所以如果可能的话,我们想使用 MEF。我尝试删除 Ninject 并设置 [Export]每个相关实现的属性,除了 Web 项目之外还跨越两个程序集,但是 Save()未能坚持下去,没有错误。我将其解释为单例问题,但无法弄清楚如何解决它(包括 [Shared] )。

  2. 我们如何在运行时动态加载多个程序集?
    我了解如何使用 CompositionContainer.AddAssemblies()要加载特定的 DLL,但为了使我们的应用程序能够正确扩展,我们需要一些更类似于我(模糊地)理解“完整”MEF 中目录的方式,这些目录已从 Microsoft.Composition 包中删除(我认为?);允许我们加载所有 IPluggable (或其他)程序集,其中将包括自己的 UI、服务和存储库层,并且也与核心服务/存储库相关联。

编辑1
一点more reading解决了第一个问题,这确实是一个单例问题。正在附加[Shared(Boundaries.HttpRequest)] CoreDbContext解决了持久化问题。当我简单地尝试[Shared]时,它将“单例化”扩展到应用程序级别(交叉请求)并抛出异常,表示编辑的对象已经在 EF 缓存中。

编辑2
我使用迭代程序集从下面 Nick Blumhardt 的答案中加载“肉”来更新我的 Global.asax.cs 代码。他的代码中的标准 MEF 2 容器在我的代码中不起作用,可能是因为我使用的是 MEF 2(?) MVC 容器。摘要:下面列出的代码现在可以按预期工作。

<小时/>

CoreDbContext.cs(Data.csproj)

[Export(typeof(IDbContext))]
[Shared(Boundaries.HttpRequest)]
public class CoreDbContext : IDbContext { ... }

CoreRepository.cs(Data.csproj)

[Export(typeof(IUnitOfWork))]
[Export(typeof(ICoreRepository))]
public class CoreRepository : ICoreRepository, IUnitOfWork
{
[ImportingConstructor]
public CoreRepository(IInsightDbContext context)
{
_context = context;
}

...
}

CoreService.cs(Services.csproj)

[Export(typeof(ICoreService))]
public class CoreService : ICoreService
{
[ImportingConstructor]
public CoreService(ICoreRepository repository, IUnitOfWork unitOfWork)
{
_repository = repository;
_unitOfWork = unitOfWork;
}

...
}

UserController.cs (Web.csproj)

public class UsersController : Controller
{
[ImportingConstructor]
public UsersController(ICoreService service)
{
_service = service;
}

...
}

Global.asax.cs (Web.csproj)

public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
CompositionProvider.AddAssemblies(
typeof(ICoreRepository).Assembly,
typeof(ICoreService).Assembly,
);

// EDIT 2 --
// updated code to answer my 2nd question based on Nick Blumhardt's answer
foreach (var file in System.IO.Directory.GetFiles(Server.MapPath("Plugins"), "*.dll"))
{
try
{
var name = System.Reflection.AssemblyName.GetAssemblyName(file);
var assembly = System.Reflection.Assembly.Load(name);
CompositionProvider.AddAssembly(assembly);
}
catch
{
// You'll need to craft exception handling to
// your specific scenario.
}
}
}
}

最佳答案

如果我理解正确的话,您正在寻找将从目录加载所有程序集并将它们加载到容器中的代码;这是执行此操作的框架:

var config = new ContainerConfiguration();
foreach (var file in Directory.GetFiles(@".\Plugins", "*.dll"))
{
try
{
var name = AssemblyName.GetAssemblyName(file);
var assembly = Assembly.Load(name);
config.WithAssembly(assembly);
}
catch
{
// You'll need to craft exception handling to
// your specific scenario.
}
}
var container = config.CreateContainer();
// ...

Hammett 讨论了这种情况,并在此处展示了 F# 中更完整的版本:http://hammett.castleproject.org/index.php/2011/12/a-decent-directorycatalog-implementation/

请注意,这不会检测应用程序启动后添加到目录中的程序集 - Microsoft.Composition 不适用于此类用途,因此,如果插件集发生更改,您最好的选择是使用以下命令进行检测:目录观察程序并提示用户重新启动应用程序。呵呵!

关于asp.net-mvc - 我们如何使用 ASP.NET MVC 4 和 MEF 2 支持模块化和可测试模式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11835473/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com