Нужна помощь с Castle.Windsor как Asp.Net MVC ControllerFactory, пожалуйста - PullRequest
1 голос
/ 22 мая 2009

Я пытаюсь реализовать WinsorControllerFactory Стивена Сандерсона из его профессиональной книги по Asp.Net MVC Framework (отличная книга, кстати), и я сталкиваюсь с проблемой. Я не уверен, что еще вам нужно знать, чтобы сформулировать ответ, но я очень ценю любую помощь в этом. Спасибо!

Вот код:

WindsorControllerFactory

public class WindsorControllerFactory : DefaultControllerFactory
{
    private WindsorContainer _container;

    public WindsorControllerFactory()
    {
        _container= new WindsorContainer(new XmlInterpreter(new ConfigResource("castle")));
        var controllerTypes = from t in Assembly.GetExecutingAssembly().GetTypes()
                              where typeof (IController).IsAssignableFrom(t)
                              select t;
        foreach(Type t in controllerTypes)
        {
            _container.AddComponentLifeStyle(t.FullName, t, LifestyleType.Transient);
        }
    }
    protected override IController GetControllerInstance(Type controllerType)
    {
        return (IController)_container.Resolve(controllerType);
    }
}

Web.Config

  <castle>
    <components>
      <component id="MenuRepository"
                 service="****.IMenuRepository, ****.Model"
                 type="****.FakeMenuRepository, ****.Model">
      </component>
      <component id="NewsRepository"
                 service="****.INewsRepository, ****.Model"
                 type="****.FakeNewsRepository, ****.Model">
      </component>
    </components>
  </castle>

NewsArticleController

public class NewsArticleController : Controller
{
    private INewsRepository _repository { get; set; }
    public NewsArticleController(INewsRepository repository)
    {
        _repository = repository;
    }

Global.asax

    protected void Application_Start()
    {
        RegisterRoutes(RouteTable.Routes);
        ControllerBuilder.Current.SetControllerFactory((new WindsorControllerFactory()));
    }

СООБЩЕНИЕ ОБ ОШИБКЕ Не найдено ни одного компонента для поддержки сервиса ****. NewsArticleController Описание: во время выполнения текущего веб-запроса произошло необработанное исключение. Пожалуйста, просмотрите трассировку стека для получения дополнительной информации об ошибке и о том, где она возникла в коде.

Exception Details: Castle.MicroKernel.ComponentNotFoundException: No component for supporting the service ****.NewsArticleController was found

Source Error:

Line 29:         protected override IController GetControllerInstance(Type controllerType)
Line 30:         {
Line 31:             return (IController)_container.Resolve(controllerType);
Line 32:         }
Line 33:     }

Ответы [ 3 ]

2 голосов
/ 09 июня 2009

MvcContrib предлагает несколько методов расширения для регистрации контроллеров в Windsor, например:

windsorContainer.RegisterControllers(Assembly.GetExecutingAssembly());

Код Манниша использует тот же метод расширения.

2 голосов
/ 22 мая 2009

В проекте S # arpArchitecture есть неплохое применение Windsor в качестве DI-фреймворка (для контроллеров или чего-либо еще), при этом практически не требуется добавлять разделы web.config - http://code.google.com/p/sharp-architecture/

Примеры кода:

CastleWindsor / ComponentRegistrar.cs:

public class ComponentRegistrar
{
    public static void AddComponentsTo(IWindsorContainer container) {
        AddGenericRepositoriesTo(container);
        AddCustomRepositoriesTo(container);

        container.AddComponent("validator",
            typeof(IValidator), typeof(Validator));
    }

    private static void AddCustomRepositoriesTo(IWindsorContainer container) {
        container.Register(
            AllTypes.Pick()
            .FromAssemblyNamed("Northwind.Data")
            .WithService.FirstNonGenericCoreInterface("Northwind.Core"));
    }

    private static void AddGenericRepositoriesTo(IWindsorContainer container) {
        container.AddComponent("entityDuplicateChecker",
            typeof(IEntityDuplicateChecker), typeof(EntityDuplicateChecker));
        container.AddComponent("repositoryType",
            typeof(IRepository<>), typeof(Repository<>));
        container.AddComponent("nhibernateRepositoryType",
            typeof(INHibernateRepository<>), typeof(NHibernateRepository<>));
        container.AddComponent("repositoryWithTypedId",
            typeof(IRepositoryWithTypedId<,>), typeof(RepositoryWithTypedId<,>));
        container.AddComponent("nhibernateRepositoryWithTypedId",
            typeof(INHibernateRepositoryWithTypedId<,>), typeof(NHibernateRepositoryWithTypedId<,>));
    }
}

Global.asax (основной метод инициализации для di):

protected virtual void InitializeServiceLocator() {
        IWindsorContainer container = new WindsorContainer();
        ControllerBuilder.Current.SetControllerFactory(new WindsorControllerFactory(container));

        container.RegisterControllers(typeof(HomeController).Assembly);
        ComponentRegistrar.AddComponentsTo(container);

        ServiceLocator.SetLocatorProvider(() => new WindsorServiceLocator(container));
    }
1 голос
/ 29 сентября 2011

Не забудьте функцию ReleaseController в WindsorControllerFactory, иначе ваш рабочий процесс исчерпает память, потому что контроллеры не освобождены.

...