MEF错误消息 - VS2010

时间:2015-11-10 11:14:24

标签: asp.net visual-studio-2010 mef

有人可以帮我解释一下这个错误信息:

system.componentmodel.composition.changerejectedexception

The composition remains unchanged. The changes were rejected because of the following error(s): The composition produced a single composition error. 
The root cause is provided below. Review the CompositionException.Errors property for more detailed information.

1) No exports were found that match the constraint: 
ContractName    Itok.BusinessLogic.Interfaces.IFolderService
RequiredTypeIdentity    Itok.BusinessLogic.Interfaces.IFolderService

Resulting in: Cannot set import 'Itok.Web.Photos.Presenters.DefaultPresenter._folderService (ContractName="Itok.BusinessLogic.Interfaces.IFolderService")' on part 'Itok.Web.Photos.Presenters.DefaultPresenter'.

Element: Itok.Web.Photos.Presenters.DefaultPresenter._folderService (ContractName="Itok.BusinessLogic.Interfaces.IFolderService") --> Itok.Web.Photos.Presenters.DefaultPresenter

这是IFolderService.cs:

using System;
using System.Collections.Generic;
using Itok.Entities;

namespace Itok.BusinessLogic.Interfaces
{
    public interface IFolderService
    {
        List<Folder> GetFriendsFolders(Int32 AccountID);
        void DeleteFolder(Folder folder);
        List<Folder> GetFoldersByAccountID(Int32 AccountID);
        Folder GetFolderByID(Int64 FolderID);
        Int64 SaveFolder(Folder folder);
    }
}

这是导出类定义FolderService.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Itok.BusinessLogic.Interfaces;
using System.ComponentModel.Composition;
using Itok.DataAccess.Interfaces;
using Itok.Common;
using Itok.DataAccess;
using Itok.Interfaces;
using Itok.Entities;

namespace Itok.BusinessLogic
{    
    [Export(typeof(IFolderService))]    
    [Export(typeof(ICache))]
    public class FolderService : IFolderService
    {
        [Import]
        private IFriendRepository _friendRepository;
        [Import]
        private IFolderRepository _folderRepository;
        [Import]
        private ICache _cacheService;

        public FolderService()
        {
            MEFManager.Compose(this);
        }

        public List<Folder> GetFriendsFolders(Int32 AccountID)
        {
            List<Friend> friends = _friendRepository.GetFriendsByAccountID(AccountID);
            List<Folder> folders = _folderRepository.GetFriendsFolders(friends);
            folders.OrderBy(f => f.CreateDate).Reverse();
            return folders;
        }

         public void DeleteFolder(Folder folder)
        {   
            if (_cacheService.Exists(folder.AccountID.ToString()))
            {
                _cacheService.Delete(folder.AccountID.ToString());
            }

            _folderRepository.DeleteFolder(folder);
        }

        public List<Folder> GetFoldersByAccountID(int AccountID)
        {        
            List<Folder> cachedFolders = _cacheService.Get(AccountID.ToString()) as List<Folder>;
            if (cachedFolders != null)
            {
                return cachedFolders;
            }
            else
            {
                cachedFolders = _folderRepository.GetFoldersByAccountID(AccountID);
                _cacheService.Set(AccountID.ToString(), cachedFolders);
                return cachedFolders;
            }
        }

        public Folder GetFolderByID(Int64 FolderID)
        {
            return _folderRepository.GetFolderByID(FolderID);
        }

        public Int64 SaveFolder(Folder folder)
        {
            return _folderRepository.SaveFolder(folder);
        }
    }
}

在为节省时间之前提供任何帮助之前,我感谢你。

2 个答案:

答案 0 :(得分:0)

错误消息表示MEF正在查找使用接口IFolderService导出的类,但容器中没有该类。

要对此进行调查,首先检查是否有一个类导出该接口,如果存在,则查看该类是否被容器拾取,第三,如果这两个类都没有解决问题,请查看使用接口IFolderService导出的类是否具有一些无法满足的其他导入。

答案 1 :(得分:0)

最后,我找到了问题的解决方案。它与MEF指向的IFolderService无直接关系。应用程序依赖于业务逻辑中的组件(FolderService),而组件又依赖于接口ICache和实现包装器Cache.cs。由合同名称Itok.Interfaces.ICache指定的ICache已导出四次(仅在一次导入时)。在我尝试扩展解决方案时,这一点未被注意到。 MEF无法分辨使用哪个Export。真正的问题是MEF指向链上层的两级!

感谢TomDoesCode查看问题,我希望这会帮助那些会遇到类似问题的人。

这个问题的长期解决方案是,如果您有许多将满足导入的导出,您可能有两个选择:

I)用[ImportMany]更改[Import]。然后在运行时期间,确定要用于合同的导入。问问自己是否只是拿起第一个可用的,或者一次一个地使用一个。

II)将[ImportMany]与元数据结合使用,以决定使用哪个导入。