所以我们让MEF使用MVC4,基于约定的模型怎么样?

时间:2013-05-18 16:40:05

标签: asp.net-mvc-4 mef

经过多次挖掘后,我认为可以在MVC4中使用MEF作为DI,在SO链接下面给出了几个例子:

How to integrate MEF with ASP.NET MVC 4 and ASP.NET Web API

他们的工作正常,但我想知道如何消除显式“导入”和“导出”的需要,就像MVC 4应用程序中的控制器一样?

网上有一些建议,一些顶级编程思想的博客。但我在复制他们的成功故事方面收效甚微。仅仅列出一对夫妇:

有什么建议吗?

2 个答案:

答案 0 :(得分:1)

.NET 4.0附带的版本没有内置的方法来执行此操作。我认为MEF 2附带4.5,它还有更多选项,包括naming conventions。您可以在NuGet上的某个地方下载并使用.NET 4.0。

Microsofts开源库的持续开发和预发布非常棒,但有时很难弄清楚每个版本中可用的功能以及哪个版本已将其纳入哪个框架。我真的找不到明确的答案......

答案 1 :(得分:0)

好的,我现在有一个解决方案。

MEFcontrib为基于会议的模型提供了良好的支持。所以简单地将它(安装包mefcontrib)添加到你的mvc 4项目中。

获得mefcontrib二进制文件后,您只需先注册约定,然后通过添加约定目录来利用它。下面的代码段显示了如何:

会议注册:

public class InitPartsConvention : PartRegistry
{
    public InitPartsConvention()
    {
        Scan(x => x.Assembly(Assembly.GetExecutingAssembly()));

        Part()
            .ForTypesAssignableFrom<IHttpController>()
            .MakeNonShared()
            .Export()
            .Imports(x =>
            {
                x.Import().Members(
                    m => new[] {
                                 m.GetConstructors()
                                 .FirstOrDefault(
                                    c => c.GetCustomAttributes(typeof(ImportingConstructorAttribute), false).Length > 0) 
                                    ?? m.GetGreediestConstructor()
                             });

                x.Import().Members(
                    m => m.GetMembers(BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic)
                        .Where(
                        mbr => mbr.GetCustomAttributes(typeof(ImportAttribute), false).Length > 0).ToArray()
                        );
            });

        Part()
            .ForTypesAssignableFrom<IController>()
            .MakeNonShared()
            .Export()
            .Imports(x =>
            {
                x.Import().Members(
                    m => new[] {
                                 m.GetConstructors()
                                 .FirstOrDefault(
                                    c => c.GetCustomAttributes(typeof(ImportingConstructorAttribute), false).Length > 0) 
                                    ?? m.GetGreediestConstructor()
                             });

                x.Import().Members(
                    m => m.GetMembers(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Where(
                        mbr => mbr.GetCustomAttributes(typeof(ImportAttribute), false).Length > 0).ToArray()
                        );
            });
    }
}

这会注册您的api控制器和mvc控制器,以便它们可以被MEFified。但它并未涵盖AsyncController。

MEF MVC bootstrapper

public static class MefBootstrapper
{
    public static void RegisterMef()
    {
        var container = GetContainer();
        var resolver = new MefDependencyResolver(container);
        // Install MEF dependency resolver for MVC
        DependencyResolver.SetResolver(resolver);

        // Install MEF dependency resolver for Web API
        System.Web.Http.GlobalConfiguration.Configuration.DependencyResolver 
            = resolver;
    }

    private static CompositionContainer GetContainer()
    {
        var path = HostingEnvironment.MapPath("~/bin");
        if (path == null) throw new Exception("Unable to find the path");

        var catelog = new AggregateCatalog(
            new DirectoryCatalog(path),
            new ConventionCatalog(new InitPartsConvention()));  // this adds the convention to MEF
        return new CompositionContainer(catelog);
    }
}

就是这样,完成了工作!在MVC 4应用程序中享受动态DI。