2009-02-27 2 views
4

Я пытаюсь получить структуру структуры, чтобы правильно создавать мои контроллеры, я использую DI для ввода INewsService в NewsController, и это единственный конструктор, который у меня есть.ASP.NET MVC, MVCContrib, Structuremap, заставить его работать как controllerfactory?

public class NewsController : Controller 
{ 
    private readonly INewsService newsService; 

    public NewsController(INewsService newsService) 
    { 
     this.newsService = newsService; 
    } 

    public ActionResult List() 
    { 
     var newsArticles = newsService.GetNews(); 
     return View(newsArticles); 
    } 
} 

, и я использую этот код, чтобы запустить приложение

public class Application : HttpApplication 
{ 
    protected void Application_Start() 
    { 
     RegisterIoC(); 
     RegisterViewEngine(ViewEngines.Engines); 
     RegisterRoutes(RouteTable.Routes); 
    } 

    public static void RegisterIoC() 
    { 
     ObjectFactory.Initialize(config => { 
      config.UseDefaultStructureMapConfigFile = false; 
      config.AddRegistry<PersistenceRegistry>(); 
      config.AddRegistry<DomainRegistry>(); 
      config.AddRegistry<ControllerRegistry>(); 
     }); 
     DependencyResolver.InitializeWith(new StructureMapDependencyResolver()); 
     ControllerBuilder.Current.SetControllerFactory(typeof(IoCControllerFactory));    
    } 
} 

Но StructureMap, кажется, не хотят, чтобы впрыснуть INewsService и я получаю ошибку Нет конструктор без параметров определяется для данного объекта ,

Что я пропустил?

ответ

6

Я использую механизм «Стандартные соглашения», который StructureMap обеспечивает, чтобы не нужно индивидуально настраивать каждый интерфейс. Ниже приведен код, я использую, чтобы сделать эту работу:

Мой Global.asax имеет эту строку в Application_Start (который использует StructureMap завод из MvcContrib):

protected void Application_Start() 
{ 
    RegisterRoutes(RouteTable.Routes); 
    ObjectFactory.Initialize(x => 
    { 
     x.AddRegistry(new RepositoryRegistry()); 
    }); 
    ControllerBuilder.Current.SetControllerFactory(typeof(StructureMapControllerFactory)); 
} 

и класс RepositoryRegistry выглядит следующим образом:

public class RepositoryRegistry : Registry 
{ 

    public RepositoryRegistry() 
    { 
     Scan(x => 
     { 
      x.Assembly("MyAssemblyName"); 
      x.With<DefaultConventionScanner>(); 
     }); 

    } 

} 

DefaultConventionScanner ищет пар интерфейсов/классов, которые следуют nameing условности ISomethingOrOther и SomethingOrOther и автоматически связывает последний в качестве конкретного типа для бывшего интерфейса.

Если вы не хотите использовать этот механизм конвенции по умолчанию, то можно добавить код в классе реестра в явной форме отображения каждого из интерфейсов конкретных типов с этим синтаксисом:

ForRequestedType<ISomethingOrOther>().TheDefaultIsConcreteType<SomethingOrOther>(); 
+0

Спасибо !, это очень помогло мне, я смог обойти мою проблему :) –

+0

@Erv какое пространство имен находится в Scan? Кажется, мне не хватает использования или ссылки. – ahsteele

+0

В используемой нами версии (которая на 8 месяцев устарела - я не смотрел, что недавно изменилось), Scan - это метод в базовом классе реестра, который наследует RespositoryRegistry из примера. –

0

Если мне что-то не хватает, вы не сообщите StructureMap, какой конкретный тип использовать для INewsService. Вам нужно добавить что-то вроде:

TheConcreteTypeOf<INewsService>.Is<MyConcreteNewsService>(); 

Я не знаю точного синтаксиса с верхней части моей головы, но это то, что вам не хватает. После того, как вы укажете это, он узнает, какой экземпляр INewsService вводится в контроллер.

+0

Я добавляю все правильные сопоставления в реестрах, таких как INewsService, поэтому не должно быть, что это вызывает проблему. –

+0

Я не использую код, в котором вы его создаете. – Micah

+0

Можете ли вы показать код в реестрах? – Micah

0

ASP. NET MVC в настоящее время создает экземпляры контроллеров, используя конструктор без параметров без параметров, который исключает любую инъекцию зависимостей на основе конструктора. Для этого вам действительно нужно использовать проект MvcContrib, который имеет встроенную поддержку StructureMap (и Castle/Spring.NET/Unity), хотя текущая документация не существует (буквально вы получаете страницу-заглушку, не хороший знак). Пример кода Erv Walter в этом потоке показывает, как настроить интеграцию StructureMap.