Импорт не разрешает необходимый тип в asp.net MVC 3 с mef - PullRequest
2 голосов
/ 17 сентября 2011

Я использовал пример для extensible asp.net mvc 3 , чтобы создать мое подключаемое приложение, но столкнулся с проблемой. В плагине я объявил и реализовал интерфейс.

Но в подключаемом контроллере, когда я хочу использовать этот класс, приложение выдает ошибку, и кажется, что EntityConfig не был инициализирован. Как это можно исправить?

[Export(typeof(IController)), ExportMetadata("controllerName", "Concept")]
[PartCreationPolicy(CreationPolicy.NonShared)]
public class ConceptController : Controller
{
   [Import(typeof(IEntityConfig))]
  private IEntityConfig EntityConfig;

  public ActionResult Index()
  {
     var obs = EntityConfig.EntityName;
      return View("~/Bin/Views/Concept/Index.cshtml",obs );
  } 
}

public interface IEntityConfig
{
    string EntityName { get;}
}

[Export(typeof(IEntityConfig))]
public class TestEntity : IEntityConfig
{
    public string EntityName
    {
       get{return "Test";}       
    }
}

Отредактировано: С другой стороны, когда я использую этот пример, нет проблем с разрешением EntityConfig, но с точки зрения, когда я хочу загрузить модель следующим образом:

@using Concepts
@model Concepts.Models.TestModel

приложение выдает ошибку и сообщает мне: «Тип или имя пространства имен« Концепции »не могут быть найдены», хотя, когда я проверяю контейнер после того, как он был инициирован, я вижу «Концепции» в загруженных сборках ».

Не могли бы вы помочь мне? Спасибо.

Отредактировано : Я загрузил образцы:

Первый

Второй

Отредактировано (2011/22/09): Я тестировал приведенный выше код на другом образце , который @Matthew Abbott предоставил в своем блоге, и он работал, хотя этот пример был создан на основе mvc 2.0.

1 Ответ

1 голос
/ 20 сентября 2011

Просматривая свой код, можете ли вы быть уверены, что часть действительно импортируется? Ваш код конструктора для вашего составного контейнера такой:

var discoverableControllerFactory = new DiscoverableControllerFactory(
    new CompositionContainer(
        new DirectoryCatalog(extensionsPath))
        );

Вы включаете только свой путь расширения в каталог. Можете ли вы гарантировать, что вы также указали путь к базовому приложению, например:

var discoverableControllerFactory = new DiscoverableControllerFactory(
    new CompositionContainer(
        new AggregateCatalog(
        new DirectoryCatalog("bin"),
        new DirectoryCatalog(extensionsPath)))
        );

Если части действительно существуют в вашем контейнере Unity, вы можете добавить поставщика экспорта, который извлекает эти части из этого контейнера и позволяет их составлять MEF.

Что касается вашей второй проблемы, вам нужно будет создать подкласс System.Web.WebPages.Razor.RazorBuildProvider, чтобы он включал сборки в каталоге расширений:

namespace ExtensibleMvcApplication
{
    public class CustomRazorBuildProvider : RazorBuildProvider
    {
        public static IEnumerable<Assembly> _assemblies;

        static CustomRazorBuildProvider()
        {
            string extensionsPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Extensions");

            _assemblies = Directory.GetFiles(extensionsPath, "*.dll")
                .Select(Assembly.Load);
        }

        public override void GenerateCode(System.Web.Compilation.AssemblyBuilder assemblyBuilder)
        {
            foreach (var assembly in _assemblies)
                assemblyBuilder.AddAssemblyReference(assembly);

            base.GenerateCode(assemblyBuilder);
        }
    }
}

Что вам нужно зарегистрировать в вашей конфигурации:

<buildProviders>
    <remove extension=".cshtml" />
    <add extension=".cshtml" type="ExtensibleMvcApplication.CustomRazorBuildProvider, ExtensibleMvcApplication"/>
</buildProviders>
...