1

プラグイン アーキテクチャ (他の MVC4 プロジェクト) とその依存関係を処理するために、MEF と Unity を統合した Microsft MVC4 アプリを作成しています。ただし、Unity の依存関係を含む MEF インポート コントローラーを選択しようとすると、エラーが発生します。エラーは次のとおりです。

1) 構築するコンストラクタを選択できなかったため、タイプ 'X' のインスタンスを作成できません。型に既定のコンストラクター、または「System.ComponentModel.Composition.ImportingConstructorAttribute」でマークされた単一のコンストラクターがあることを確認してください。

メインの MVC4 アプリ MEF + Unity 統合コード:

// Create MEF catalog from plugin directory.
var aggregateCatalog = new AggregateCatalog(new DirectoryCatalog(HostingEnvironment.MapPath("~/bin"), "*.dll"));

// Setup Unity container based on catalog.
var unityContainer = new UnityContainer();
unityContainer.RegisterCatalog(aggregateCatalog);  

// Register dependancy.
unityContainer.RegisterType<ISystemService, SystemService>();

// Compose the MEF container.
CompositionContainer container = new CompositionContainer(aggregateCatalog, true);
container.ComposeParts(aggregateCatalog.Catalogs);

// Register the controller factory that will handle requests.
ControllerBuilder.Current.SetControllerFactory(new MefControllerFactory(container));
var dependencyResolver = System.Web.Http.GlobalConfiguration.Configuration.DependencyResolver;
System.Web.Http.GlobalConfiguration.Configuration.DependencyResolver = new MefDependencyResolver(container);

MEF から適切なコントローラーを選択する CreateController メソッド

// Get all the exported controllers.
var exports = _container.GetExports<IController, INameMetadata>();

// Select controller based off meta data.
var controller = exports.Where(e => e.Metadata.Name.ToLower().Equals(controllerName.ToLower())
            && e.Metadata.Module.ToLower().Equals(module.ToLower()))
    .Select(e => e.Value).FirstOrDefault();            

インポートしようとしているコントローラーのセットアップ。これは、抽象基本クラスのサブクラスです。

基本クラス。

public abstract class WidgetController : Controller
{

    [Dependency]
    public ISystemService _systemService { get; set; }

    [ImportingConstructor]
    public WidgetController(ISystemService systemService)
    {
        _systemService = systemService;
    }
}

子クラス。

[InheritedExport(typeof(IController))]
[ExportMetadata("Module", "TheComponent")]
[ExportMetadata("Name", "TheName")]
[PartCreationPolicy(CreationPolicy.NonShared)]
public class WidgetXController : WidgetController 
{    
    public WidgetXController (ISystemService systemService)
        : base(systemService)
    {      
    }
}

この構造により、WidgetXController は CreateController メソッドのエクスポートとして使用できます。ただし、LINQ クエリで選択しようとすると、上記のエラー メッセージが表示されます。[ImportingConstructor] 属性を子クラスに追加しようとしましたが、その結果、コントローラーがエクスポート リストに入りません。MEF + Unity 統合で何かが正しく設定されていないと思います...

MEF + Unity 統合がどのように機能し、表示されたエラーを解決するのに役立つかについて、誰か洞察を持っていますか?

4

1 に答える 1

1

解決策を見つけました。新しいコンポジション コンテナーを作成する代わりに、Unity から取得する必要がありました。

したがって、元のコードは次のとおりです。

// Compose the MEF container.
CompositionContainer container = new CompositionContainer(aggregateCatalog, true);
container.ComposeParts(aggregateCatalog.Catalogs);

// Register the controller factory that will handle requests.
ControllerBuilder.Current.SetControllerFactory(new MefControllerFactory(container));
var dependencyResolver = System.Web.Http.GlobalConfiguration.Configuration.DependencyResolver;
System.Web.Http.GlobalConfiguration.Configuration.DependencyResolver = new MefDependencyResolver(container);

なる:

// Obtain the MEF container from Unity
var mefContainer = unityContainer.Resolve<CompositionContainer>();
mefContainer.ComposeParts(this);

// Register the controller factory that will handle requests.
ControllerBuilder.Current.SetControllerFactory(new MefControllerFactory(mefContainer));
var dependencyResolver = System.Web.Http.GlobalConfiguration.Configuration.DependencyResolver;
System.Web.Http.GlobalConfiguration.Configuration.DependencyResolver = new MefDependencyResolver(mefContainer);
于 2013-09-03T14:26:48.797 に答える