加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

asp.net-mvc – 我们如何使用ASP.NET MVC 4和MEF 2支持模块化和

发布时间:2020-12-16 09:51:41 所属栏目:asp.Net 来源:网络整理
导读:我们正在尝试将MEF 2与ASP.NET MVC 4一起使用来支持可扩展的应用程序.这个问题实际上有两个部分(希望没关系,所以这就是神): 我们如何使用Microsoft.Composition和MVC容器代码(MEF/MVC demo source)将Ninject替换为ICoreService,ICoreRepository,IUnitOfWork
我们正在尝试将MEF 2与ASP.NET MVC 4一起使用来支持可扩展的应用程序.这个问题实际上有两个部分(希望没关系,所以这就是神):

>我们如何使用Microsoft.Composition和MVC容器代码(MEF/MVC demo source)将Ninject替换为ICoreService,ICoreRepository,IUnitOfWork和IDbContext的DI?
看起来我们不能同时使用Ninject和MVC容器(我确信很多人都在说“duh”),所以如果可能的话,我们想和MEF一起使用.我尝试删除Ninject并在每个相关实现上设置[Export]属性,除了Web项目之外还包含两个程序集,但Save()无法保持没有错误.我将其解释为单例问题,但无法弄清楚如何对其进行排序(包括[共享]).
>我们如何在运行时动态加载多个程序集?
我理解如何使用CompositionContainer.AddAssemblies()来加载特定的DLL,但是为了使我们的应用程序能够正确扩展,我们需要更类似于我(模糊地)理解“完整”MEF中的目录的内容,这些内容已被从中删除Microsoft.Composition包(我想?);允许我们加载所有IPluggable(或其他)程序集,这些程序集将包括它们自己的UI,服务和存储库层,并且也可以绑定到Core服务/存储库.

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

编辑2
我使用了来自Nick Blumhardt的答案的迭代程序集“meat”来更新我的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不适合这种用途,因此如果插件集更改,最好的办法是使用目录监视器检测到并提示用户重新启动应用程序. HTH!

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读