2012-04-11 2 views
5

У нас есть решение с несколькими проектами, представляющими слои нашего приложения. , например.Возможно ли, что Castle Windsor разрешает имущественные зависимости, если у вас нет ссылки на контейнер?

домена

данных

Logic

WebUI

Наш Виндзорский замок контейнера ссылки с нашего веб-слоя, и мы затем каскадом эти зависимостей через наши слои. Например ...

// In Domain 
public interface IFooRepository 
{ 
    void DoSomething(); 
} 

// In Data 
public class FooRepository : IFooRepository 
{ 
    public void DoSomething() 
    { 
     // Something is done 
    } 
} 

// In Logic 
public class MyThingManager 
{ 
    private readonly IFooRepository fooRepository; 

    public MyThingManager(IFooRepository fooRepository) 
    { 
     this.fooRepository = fooRepository; 
    } 

    public void AMethod() 
    { 
     this.fooRepository.DoSomething(); 
    } 

} 

// In Web 
// in some controller.... 
var newManager = new MyThingManager(WindsorContainer.Resolve<IFooRepository>()); 
newManager.DoSomething(); 

, и это работает прекрасно, пока у наших менеджеров не будет много членов, у которых есть свои собственные зависимости. Когда это происходит, мы в конечном итоге устраняем как зависимостей менеджеров, так и их зависимостей зависимостей и каскадируем их с веб-уровня. Это приводит к некоторым довольно крупным конструкторам.

Есть ли более элегантный способ, например, если внутренние компоненты менеджера разрешают его собственные зависимости без доступа к контейнеру?

Имейте в виду, что ТОЛЬКО веб-слой имеет доступ к контейнеру (чтобы предотвратить круговую зависимость проекта), так что только веб-слой может активировать WindsorContainer.Resolve() логический уровень не может, поэтому единственный способ каскадирования зависимость без помощи контейнеров заключалась в том, чтобы разрешить ее в веб-слое, а затем передать ее цепочке, используя ее интерфейс.

+2

«В конечном итоге мы разрешаем как зависимостей менеджеров, так и их зависимостей от наложения и каскадирования их из веб-уровня». Я этого не понимаю. Когда вы используете инъекцию конструктора и позволяете контейнеру автоматически вводить зависимости в конструкторе типа, не должно быть никаких проблем. Показать немного больше кода визуализации этой проблемы может быть полезно. – Steven

ответ

6

Короткий ответ: каждый раз, когда вы видите .Resolve<T>, вы, вероятно, doing it wrong. Как отметил @Steven, вы хотите использовать встроенные функции Windsor, чтобы предоставить вам инъекцию конструктора (и/или инъекцию свойств). Это означает, что WindsorContainer должен знать объект, который находится в корне вашего графа объектов.

В вашем случае вы должны подойти к дереву объектов (от MyThingyManager), пока не дойдете до корневого объекта. Например, в приложении ASP.NET MVC это будет контроллер, который содержит вызываемое действие. Для случая MVC3 вы должны использовать DependencyResolver, чтобы начать инъекцию всех зависимостей.

Кроме того, то, что я нашел полезным в Windsor в прошлом, состоит в том, чтобы иметь другой установщик на один компонент (сборку). А затем зарегистрируйте эти установщики в базе процесса, на котором размещено приложение.

Таким образом, в каждом компоненте вы бы инсталлятор, как:

public class Installer : IWindsorInstaller 
{ 
     public void Install(Castle.Windsor.IWindsorContainer container, Castle.MicroKernel.SubSystems.Configuration.IConfigurationStore store) 
     { 
      container.Register(
       Component.For<IMyThingManager>().ImplementedBy<MyThingManager>(), 
       Component.For<IFooRepository>().ImplementedBy<FooRepository>() 
       ); 
     } 
} 

, а затем в Global.asax.cs Application_Start вы бы иметь что-то вроде:

var container = new WindsorContainer(); 
container.Install(FromAssembly.This()); 
container.Install(FromAssembly.Containing(typeof(ComponentThatContains.MyThingManager.Installer))); 

Это дает вам способ управлять всеми зависимостями по всему графику объекта и разрешать его путем встраивания конструктора. Надеюсь, это поможет.

+0

Спасибо за это, он начал полное переосмысление того, как мы делаем МОК, и теперь он работает как магия: D –

+0

Приятно слышать, рад, что я мог бы помочь. –

Смежные вопросы