首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MEF2与.NET核心

MEF2与.NET核心
EN

Stack Overflow用户
提问于 2016-09-14 04:08:07
回答 1查看 1.6K关注 0票数 4

我一直在读到MEF还活着等等.

我还读到,我只需要替换void ConfigureServices(IServiceCollection services)IServiceCollection ConfigureServices(IServiceCollection services)就可以提供我自己的容器(在我的例子中,MEF容器).

我的问题是我找不到正确的return。你看,CompositionHost没有实现IServiceCollection..。

有人能教我如何使用MEF2作为.NET核心webapi上的容器吗?

EN

回答 1

Stack Overflow用户

发布于 2020-09-25 10:27:18

这似乎很旧,我希望不会太晚。

下面是你需要做的事情:

先决条件:Eml.MefBootstrapper

  1. 实现IControllerActivator
代码语言:javascript
复制
//using System.Composition.Hosting;
//using Microsoft.AspNetCore.Mvc;
//using Microsoft.AspNetCore.Mvc.Controllers;
public class MefControllerActivator : IControllerActivator
{
       private readonly CompositionHost container;

       public MefControllerActivator(CompositionHost c) { container = c; }

       public object Create(ControllerContext c) => container.GetExport(c.ActionDescriptor.ControllerTypeInfo.AsType());

       public void Release(ControllerContext c, object controller) { }
}
  1. 创建扩展方法。示例:
代码语言:javascript
复制
//using Eml.ClassFactory.Contracts;
//using Microsoft.AspNetCore.Hosting;
//using Microsoft.AspNetCore.Mvc.Controllers;
//using Microsoft.Extensions.DependencyInjection;
//using Microsoft.Extensions.Logging;
//using System;

    public static class MefService
    {
        /// <summary>
        /// Call this in Startup.ConfigureServices.
        /// Use Mef to resolve controllers. Hooks with ApplicationStopping for Mef disposal.
        /// Already have a reference to Eml.MefBootstrapper. Remove references to Eml.MefBootstrapper when using this to avoid version mismatch.
        /// </summary>
        /// <param name="serviceCollection"></param>
        /// <param name="bootstrapper"></param>
        public static IClassFactory AddMef(this IServiceCollection serviceCollection, Func<IClassFactory> bootstrapper)
        {
            var serviceProvider = serviceCollection.BuildServiceProvider();

            // Create Mef container
            var classFactory = bootstrapper();

            //Register MefControllerActivator
            serviceCollection.AddSingleton<IControllerActivator>(new MefControllerActivator(classFactory.Container));

            //Graceful exit
            var appLifetime = serviceProvider.GetService<IApplicationLifetime>();
            var loggerFactory = serviceProvider.GetService<ILoggerFactory>();

            appLifetime.ApplicationStopping.Register(() =>
            {
                var logger = loggerFactory.CreateLogger("Global logger");

                logger.LogDebug("Disposing Mef...");
                Eml.Mef.ClassFactory.Dispose(classFactory);
            });

            return classFactory;
        }
    }
  1. 创建IServiceCollection扩展以在Startup.cs中使用
代码语言:javascript
复制
//using Eml.ClassFactory.Contracts;
//using Eml.Mef;
//using Microsoft.Extensions.DependencyInjection;
//using Microsoft.Extensions.Logging;
//using System;
//using System.Collections.Generic;
//using System.Composition.Hosting;
//using System.Composition.Hosting.Core;
//using Trackinator.Api.Helpers.Mef;
//using Trackinator.Infrastructure;

    public static class MefStartup
    {
        public static IClassFactory ConfigureMefService(this IServiceCollection services, ILoggerFactory loggerFactory)
        {
            return services.AddMef(() =>
            {
                // Register instances as shared.
                var instanceRegistrations = new List<Func<ContainerConfiguration, ExportDescriptorProvider>>
                {
                        r => r.WithInstance(loggerFactory)
                };

                // Create Mef container
                //return Bootstrapper.Init(Constants.ApplicationId, instanceRegistrations);
                var classFactory = Bootstrapper.Init(new List<string> { Constants.ApplicationId, "Microsoft.AspNetCore.SignalR." }, instanceRegistrations);
                
                return classFactory;
            });
        }
    }
  1. 将这一行添加到Startup.cs中
代码语言:javascript
复制
public static IClassFactory ClassFactory { get; private set; }

public void ConfigureServices(IServiceCollection services)
{
    //..other codes
    ClassFactory = services.ConfigureMefService(LoggerFactory);

}

参见示例实现这里

祝好运!

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39482343

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档