2012-06-25 2 views
1

MvcContrib의 휴대용 영역과 MEF를 사용하여 다시 컴파일하지 않고도 휴대용 영역을 플러그인으로 추가 할 수있는 플러그인 프레임 워크를 구축합니다 (bin/Modules 폴더) 또는 플러그인 프로젝트를 직접 참조 할 수 있습니다.MEF는 어셈블리를로드 할 수 있지만 어떤 파트도로드 할 수 없습니다.

플러그인을 개발하는 동안 MyFramework와 MyPlugin이라는 두 가지 프로젝트가있는 솔루션이 있습니다. 모든 것이 잘 작동합니다. MyPlugin 프로젝트가있는 다른 솔루션이 있지만 MyPlugin.dll은 bin/Modules 폴더에 있습니다.

string Path = HostingEnvironment.MapPath("~/bin"); 
string ModulesPath = HostingEnvironment.MapPath("~/bin/Modules"); 
var catalog = new AggregateCatalog(
    new DirectoryCatalog(Path) 
    new DirectoryCatalog(ModulesPath) 
); 

카탈로그를 인스턴스화 할 때 MyPlugin.dll의 어셈블리가로드되었지만 파트가 없습니다.

string Path = HostingEnvironment.MapPath("~/bin"); 
string ModulesPath = HostingEnvironment.MapPath("~/bin/Modules"); 
var binCatalog = new DirectoryCatalog(Path); 
var modulesCatalog = new DirectoryCatalog(ModulesPath); 
var catalog = new AggregateCatalog(binCatalog, modulesCatalog); 

using (var container = new CompositionContainer(modulesCatalog)) 
{ 
    var ci = new CompositionInfo(modulesCatalog, container); 
    var stringWriter = new StringWriter(); 

    CompositionInfoTextFormatter.Write(ci, stringWriter); 
    string compositionStateString = stringWriter.ToString(); 
    Console.WriteLine(s); 
} 

을하지만 compositionStateString 그냥 빈 문자열입니다과 같이 here 설명 된대로 내가 구성 상태를 덤프 MEFx를 사용했습니다.

문제의 출처를 이해하는 데 문제가 있습니다. MyFramework는 MyPlugin에 대한 직접적인 참조가 없기 때문에 두 프로젝트가 동일한 솔루션의 일부로 컴파일되는지 여부는 중요하지 않습니다.

추가 정보 : 빈/모듈이 probing path에 있습니다. 그 속성과 같이 MyFramework에 정의되어

[ExportModuleControllerAttribute("NotificationsController")] 
public class NotificationsController : BaseController 
{ 
    //... 
} 

:

:

[AttributeUsage(AttributeTargets.Class), MetadataAttribute] 
public class ExportModuleControllerAttribute : ExportAttribute, INamedMetadata   
{ 
    public string[] Dependencies { get; set; } 
    public string Name { get; set; } 

    public ExportModuleControllerAttribute(string name, params string[] dependencies) 
     : base(typeof(IController)) 
    { 
     Dependencies = dependencies; 
     Name = name; 
    } 
} 

가 INamedMetadata 인터페이스이므로

나는 사용자 지정 수출 속성을 장식하여 컨트롤러를 수출하고있어

public interface INamedMetadata 
{ 
    #region Properties 
    string Name { get; } 
    #endregion 
} 

답변

1

@Peter는 몇 가지 좋은 점을 제시합니다. Visual MEFX를 사용해 보는 것도 좋습니다. mefcontrib-tools 프로젝트에서 찾을 수 있습니다. 그러면 대화식으로 어셈블리를 탐색 할 수 있습니다. 한 번에 하나씩 추가하고 내보낼 것이 있는지 확인할 수 있습니다. 당신은 당신이 시작 bin 폴더에 *.pdb 파일이 포함되어 있는지 확인해야합니다 Getting Started with Visual MEFX

+0

나는 그것을 조사 할 것이다. 감사. – ashanan

+0

MyPlugin.dll을 Visual MEFX로로드해도 아무런 변화가 없습니다. 나는 그 dll에 수출이 없다는 것을 의미한다고 가정한다. 그러나 그것이 분명해질 수는있다. 어쩌면 내가 잘못 내보내고있는 걸까요? – ashanan

+1

예, 내 경험상 Visual MEFX는 어셈블리에 내보내기가없는 경우 아무 작업도 수행하지 않습니다. 그것은 당신이 당신의 수출을 선언하는 방법을 단순화하려고 할 것입니다. 메타 데이터없이 일반 Export 속성을 사용하여 시작하십시오. 그런 다음 일부 메타 데이터를 추가하고 작동하는지 확인하십시오. 다행스럽게도 몇 번의 반복 작업을 통해 정확히 무엇이 잘못되었는지 정확히 알 수 있습니다. –

3

수업을 내보내는 중 (컨트롤러를 추측하고 있습니다) 등을 어떻게하고 있습니까? r 모듈 dll? 더 많은 코드를 볼 수 있습니다. 카탈로그를 설치하는 것만으로는 충분하지 않습니다. 실제로 카탈로그를 넣으라고 말해야합니다.

또한 ci.PartDefinitions에 항목이 있는지 확인하십시오. 실제로 ci와 디버거의 컨테이너 변수를 검사하고 그 안에 무엇이 있는지 확인하십시오. 또한

왜 당신은 단지 검사 modulesCatalog 당신은 어쨌든이 올바른 방향을 제시해 주었으면 카탈로그 예를 들어

var ci = new CompositionInfo(catalog, container); 

를 검사해서는 안된다.

+0

위의 질문을 편집하여 내보내기 코드를 추가했습니다. 내 실제 코드에서는 카탈로그를 검사하고 있지만 부품을 올바르게로드하지 못하는 카탈로그이므로 문제가 모듈 카탈로그와 관련되어 있음을 명확히 알 수 있다고 생각했습니다. 카탈로그를 검사하면 binCatalog 만 검사하면 얻을 수있는 것과 동일한 결과를 얻습니다. 카탈로그를 사용하여 CompositionInfo를 생성하면'ci.PartDefinitions.Count()'는 8을 반환해야 할 때 4를 반환합니다. 디버거에서 ci를 검사했지만 실제로 찾고있는 부분 이외에 무엇이 필요한지 잘 모르겠습니다. 거기있어. – ashanan

+0

app_code와 같은 다른 dirctory에 모듈을 넣으십시오. 또한 프로빙 경로 항목을 끕니다. 또한 수출과 함께 메타 데이터를 원할 경우 사용자 정의 메타 태그가 아닌 표준 Exportattribute를 사용하여 내보내기를 시도하십시오. MEf에는 해당 용도의 메타 데이터 속성이 있습니다. – Peter

0

:

여기에 그것을 설치를 얻기에 관한 기사입니다.

*.dll은 수입품을 만족시키기에 충분하지 않습니다.