MEF - 没有为此对象定义的无参数构造函数,等

时间:2015-04-02 20:37:45

标签: c# asp.net-mvc mef

我是MEF的新手并且陷入了“没有为此对象定义的无参数构造函数”的地狱。在过去的几个小时里,我看过很多帖子等,完全被卡住了。我究竟做错了什么?我正在使用。NET 4.5,所以我还需要所有这些属性吗?我是否将较旧的样式MEF与较新的混合使用?

更新:

我正在研究的解决方案也引用了Unity 3.3,所以我认为它们可能互相踩踏。我需要删除Unity吗?

    [Export]
    [PartCreationPolicy(CreationPolicy.NonShared)]
    public class HomeController : Controller
    {
        private readonly IHomeService _service;

        [ImportingConstructor]
        public HomeController(IHomeService service)
        {
            _service = service;
        }
    }

    [Export(typeof(IHomeService))]
    [PartCreationPolicy(CreationPolicy.NonShared)]
    public class HomeService : IHomeService
    {
        private readonly IServiceSearch _serviceSearch;

        [ImportingConstructor]
        public HomeService(IServiceSearch serviceSearch)
        {
            _serviceSearch = serviceSearch;
        }
    }

    [InheritedExport]
    public interface IHomeService
    {
       // ...
    }

    [Export(typeof(IServiceSearch))]
    [PartCreationPolicy(CreationPolicy.NonShared)]
    public class ServiceSearch : DataHub.Search, IServiceSearch
    {

        [ImportingConstructor]
        public ServiceSearch(IMapper<xxx, xxxDTO> x)
        {
           // ...
        }

    [InheritedExport]
    public interface IMapper<TDomain,TDto>
    {
        TDomain ToDomain(object o);
        void Initialize();
        TDto DomainToDto(TDomain domain);
    }

 [Export(typeof(IMapper<Account, AccountDTO>))]
    public class AccountMapper : IMapper<Account, AccountDTO>
    {
     //....
    }

    protected void Application_OnStart()
    {            
        var catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
        var composition = new CompositionContainer(catalog);
        IControllerFactory mefControllerFactory = new MefControllerFactory(composition); //Get Factory to be used
        ControllerBuilder.Current.SetControllerFactory(mefControllerFactory);
    }

    public class MefControllerFactory : DefaultControllerFactory
    {
        private readonly CompositionContainer _container;
        public MefControllerFactory(CompositionContainer container)
        {
            _container = container;
        }
        protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType)
        {
            Lazy<object, object> export = _container.GetExports(controllerType, null, null).FirstOrDefault();

            return null == export
                                ? base.GetControllerInstance(requestContext, controllerType)
                                : (IController)export.Value;
        }
        public override void ReleaseController(IController controller)
        {
            ((IDisposable)controller).Dispose();
        }
    }

1 个答案:

答案 0 :(得分:1)

我设法让你的代码使用这些修改:

  1. 将嵌套在ServiceSearch内的类型移到其外部。我不认为MEF支持嵌套类型。(看起来好像这只是上面代码示例中的一个错字。我不认为它是有意的。)

  2. InheritedExportAttribute移除IMapper<,>。无论如何,您在AccountMapper上都有明确的导出。如果不进行此更改,最终会导致AccountMapper导出两次。导入ServiceSearch的构造函数然后失败,因为MEF不知道要使用哪两个匹配的导出。 或者保留InheritedExportAttribute并删除显式导出。

  3. 删除InheritedExportAttribute上的IHomeServiceExportAttribute上的HomeService,原因与上述相同。